In the last post, we’ve talked about several methods that allow us to wait on one or more kernel objects until they transition into the signaled state. Today we’re going to take a look at the last method (exposed by the WaitHandle class) that we can use for waiting on an object: the SignalAndWait method. You can use one of the overloads of this method when you need to signal an existing kernel object and wait on another one until it gets into the signaled state. The coolest thing about this method is that the signaling and waiting is performed atomically! Signaling the object performs the expected operation:
- if we have a mutex, it will call the ReleaseMutex method. Notice that if the mutex has been acquired recursively, then this will decrement the internal count by one;
- if we have a semaphore, this method ends up calling ReleaseSemaphore;
- finally, if it’s an event, we end up calling the Set method.
It’s also important to keep in mind that you might end up getting exceptions. For instance, if you’re calling this method and you’re signaling a semaphore that is already “full”, then you’ll end up getting and InvalidOperationException.
Whenever you need to signal a kernel object and wait on another, you should always use this method to ensure that the operations are performed atomically.
And that’s all for today. On the next post we’ll start looking at the high level sync primitives. Keep tuned for more.