I thought that the following code would let all the 10 threads run, two at a time, and then print "done" after Release()
is called 10 times. But that's not what happened:
int count = 0;
Semaphore s = new Semaphore(2, 2);
for (int x = 0; x < 10; x++)
{
Thread t = new Thread(new ThreadStart(delegate()
{
s.WaitOne();
Thread.Sleep(1000);
Interlocked.Increment(ref count);
s.Release();
}));
t.Start(x);
}
WaitHandle.WaitAll(new WaitHandle[] { s });
Console.WriteLine("done: {0}", count);
output:
done: 6
If the only way to implement the functionality I'm looking for is to pass an EventWaitHandle
to each thread and then do a WaitAll()
on an array of those EventWaitHandles
, then what's the meaning of doing a WaitAll()
on an array of only a semaphore? In other words, when does the waiting thread unblock?
WaitHandle.WaitAll
just waits until all the handlers are in signalled state.
So when you call WaitHandle.WaitAll
on one WaitHandle
it works the same as you call s.WaitOne()
You can use, for example, the following code to wait for all the started threads, but allow two threads to run in parallel:
int count = 0;
Semaphore s = new Semaphore(2, 2);
AutoResetEvent[] waitHandles = new AutoResetEvent[10];
for (int x = 0; x < 10; x++)
waitHandles[x] = new AutoResetEvent(false);
for (int x = 0; x < 10; x++)
{
Thread t = new Thread(threadNumber =>
{
s.WaitOne();
Thread.Sleep(1000);
Interlocked.Increment(ref count);
waitHandles[(int)threadNumber].Set();
s.Release();
});
t.Start(x);
}
WaitHandle.WaitAll(waitHandles);
Console.WriteLine("done: {0}", count);