Edit: I would like to ask for temporary insanity for even asking this question, but that made sense at the time (see board 2 below).
For the .NET 3.5 project, I have two types of resources (R1 and R2) that I need to check for. Each type of resource can have (say) 10 instances at any time.
When one of the resources of any type becomes available, my worker thread should wake up (there is a variable number of threads). In an earlier implementation, there was only one type of resource for which I used Semaphore to check for availability.
Now I need to wait on two separate Semaphores (S1 and S2) that track the availability of resources.
WaitHandle[] waitHandles = new WaitHandle[] { s1, s2 }; int signalledHandle = WaitHandle.WaitAny(waitHandles); switch (signalledHandle) { case 0:
There is one problem with this, however. From the MSDN documentation on WaitAny :
If more than one object becomes a signal during a call, the return value is the index of the array of the signal object with the lowest index value for all signal objects.
This suggests that perhaps I reduced both accounts of Semaphore by 1 after calling WaitAny . Since the signalledHandle will indicate that s1 has been signaled, I will start using the R1 resource and release it when done. However, since I do not know if S2 was signaled or not, the amount of available resources on this resource can now be disabled. If this happens 10 times, my Semaphore will be “empty” forever, and resource R2 will no longer be used.
What is the best way to handle this? Should I switch from using two semaphores to simple counters and AutoResetEvent to signal when the counter changes? Is there an even more elegant approach?
Change 1:
According to Ravadra, only one of the Semaphores will actually be changed after WaitAny . Changing his example a bit seems to confirm this, but is there anyone who can point me to some kind of official documentation that points this out?
Edit 2:
I thought about it on the way home. Only then did I realize that this should be true for WaitAny . This problem will not be limited to semaphores, but only with any type of synchronization object, making WaitAny practically useless.