Implementing a wrapper around threadpool
I've noticed a common pattern in some code I'm writing so I decided to extract it into a class. However, since starting to use this class I've been having a problem where every once in a while the program will hang indefinitely, and, from what I can tell from debugging, this class seems to be the cause. Could sometime tell me what I'm doing wrong? Thank you for your time.
Updated code:
class ParallelTaskWaiter
{
int numTasksRunning;
private readonly object completeLock = new开发者_JAVA技巧 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);
}
}
}
Shouldn't that be:
private int numTasksToComplete = 0;
There isn't a task to begin with.
WAG here... Change
if (Interlocked.Decrement(ref numTasksToComplete) == 0)
to
if (Interlocked.Decrement(ref numTasksToComplete) <= 0)
Its the safer bet, no matter what.
In addition, while you are interlocking the increment, you are still incrementing THEN queueing the work item. Incrementing and queueing should be atomic. I'd also use a lock
instead of an interlocked increment.
精彩评论