我想启动一些新线程,每个线程用于一个重复操作。但是,当这一行动已经在进行时,我想放弃目前的任务。在我的场景中,我只需要非常最新的数据-删除的数据不是一个问题。
在MSDN中,我找到了Mutex类,但据我所知,它等待它的回合,阻塞当前线程。另外,我想问您:在.NET框架中已经存在一些东西,即执行以下
return (让我增加一些统计计数器)发布于 2012-02-09 11:17:42
您可能遇到过的lock(someObject)语句是Monitor.Enter和Monitor.Exit周围的语法糖。
但是,如果您以这种更详细的方式使用监视器,您还可以使用Monitor.TryEnter,它允许您检查是否能够获得锁--从而检查其他人是否已经拥有它并正在执行代码。
所以,不是这样的:
var lockObject = new object();
lock(lockObject)
{
// do some stuff
}试试这个(选项1)
int _alreadyBeingExecutedCounter;
var lockObject = new object();
if (Monitor.TryEnter(lockObject))
{
// you'll only end up here if you got the lock when you tried to get it - otherwise you'll never execute this code.
// do some stuff
//call exit to release the lock
Monitor.Exit(lockObject);
}
else
{
// didn't get the lock - someone else was executing the code above - so I don't need to do any work!
Interlocked.Increment(ref _alreadyBeingExecutedCounter);
}(您可能希望在其中放置一个try..finally,以确保锁被释放)
或取消显式锁althogether并执行此操作。
(选项2)
private int _inUseCount;
public void MyMethod()
{
if (Interlocked.Increment(ref _inUseCount) == 1)
{
// do dome stuff
}
Interlocked.Decrement(ref _inUseCount);
}this**]** [编辑:回答你关于的问题
不-不要用this来打开lock。创建一个私有的作用域对象作为您的锁。
否则,您将遇到以下潜在问题:
public class MyClassWithLockInside
{
public void MethodThatTakesLock()
{
lock(this)
{
// do some work
}
}
}
public class Consumer
{
private static MyClassWithLockInside _instance = new MyClassWithLockInside();
public void ThreadACallsThis()
{
lock(_instance)
{
// Having taken a lock on our instance of MyClassWithLockInside,
// do something long running
Thread.Sleep(6000);
}
}
public void ThreadBCallsThis()
{
// If thread B calls this while thread A is still inside the lock above,
// this method will block as it tries to get a lock on the same object
// ["this" inside the class = _instance outside]
_instance.MethodThatTakesLock();
}
}在上面的例子中,一些外部代码成功地破坏了类的内部锁定,只需取出一个外部可访问的锁。
更好的方法是创建一个您控制的私有对象,并且您的类之外的任何人都不能访问该对象,以避免此类问题;这包括不使用this或类型本身typeof(MyClassWithLockInside)进行锁定。
发布于 2012-02-09 11:19:26
一种选择是使用可重入的哨兵:
您可以定义一个int字段(用0初始化),并在输入该方法时通过Interlocked.Increment更新它,只有当它为1时才继续,最后只需执行Interlocked.Decrement。
另一种选择:
从你的描述来看,你似乎有一个制片人-消费者-场景.
在这种情况下,使用像BlockingCollection这样的东西可能会有帮助,因为它是线程安全的,而且大多是无锁的.
另一种选择是使用ConcurrentQueue或ConcurrentStack.
发布于 2012-02-09 11:16:25
您可能会在下面的站点中找到一些有用的信息( PDf也是可下载的--最近我自己下载了)。Adavnced线程挂起,并继续或中止章节,可能是什么你不知道。
https://stackoverflow.com/questions/9209590
复制相似问题