我注意到我正在编写的一些代码中有一个常见的模式,所以我决定将它提取到一个类中。但是,自从开始使用这个类以来,我遇到了一个问题,每隔一段时间程序就会无限期挂起,而且,从调试中可以看出,这个类似乎是原因。有时可以告诉我我做错了什么吗?谢谢你的时间。
更新的代码:
class ParallelTaskWaiter
{
int numTasksRunning;
private readonly object completeLock = new object();
public void WaitFor(ThreadStart action)
{
Interlocked.Increment(ref numTasksRunning);
ThreadPool.QueueUserWorkItem(delegate
{
try { action(); }
finally
{
if (Interlocked.Decrement(ref numTasksRunning) == 0)
{
lock (completeLock)
{
Monitor.PulseAll(completeLock);
}
}
}
});
}
public void Wait()
{
lock (completeLock)
{
if (Interlocked.CompareExchange(ref numTasksRunning, 0, 0) == 0) return;
Thread.SpinWait(1);
Monitor.Wait(completeLock, Timeout.Infinite);
}
}
}
答案 0 :(得分:1)
不应该是:
private int numTasksToComplete = 0;
开始时没有任务。
答案 1 :(得分:0)
WAG在这里......改变
if (Interlocked.Decrement(ref numTasksToComplete) == 0)
到
if (Interlocked.Decrement(ref numTasksToComplete) <= 0)
无论如何,它都是更安全的赌注。
此外,当您将增量互锁时,您仍然在递增那么排队工作项。增量和排队应该是原子的。我还使用lock
而不是互锁增量。