我有一个为线程池生成任务的经理类,每个线程都应该在完成后回调。
我使用锁来处理变量和字段,以及处理线程间通信的信号。我正在寻找的是一种退出当前lock()并以原子方式等待信号的方法,比如SignalAndWait,但是对于locks()。
代码看起来像这样:
// ... part of the scheduler
foreach(WorkTask task in worktasks)
{
lock(_syncObj)
{
new Job(task, myCallback); // creates a thread
instanceCount++;
while(instanceCount > _maxConcurrentTasks)
_resetEvent.WaitOne(Timeout.Infinite);
}
}
// .. the callback
void myCallback()
{
lock(_syncObj)
{
instanceCount--;
_resetEvent.Set();
}
}
这里的问题是.WaitOne()没有退出lock(),因此执行回调的任何线程都会死锁。
我对WaitOne(Int32,bool exitContext)抱有很高的期望,但这种情况似乎与远程处理有关,而不是同步。
答案 0 :(得分:3)
是否有任何理由使用事件原语而不是Monitor.Wait/Pulse/PulseAll
? Monitor.Wait
以原子方式释放锁并等待,在返回之前重新获取锁。有关详细信息,请参阅my threading article。