Multithreading: waiting on kernel objects

Until now, we’ve seen how we can wait on several synchronization kernel objects until a specific condition is met. All the examples we’ve seen ended up using the simple WaitOne method.Today we’re going to take a look at the other “waiting” methods inherited from the base WaitHandle class: WaitAny and WaitAll.

You’ll need these static methods whenever you need to wait on several kernel objects. WaitAll will only unblock when all objects have reached the signaled state; WaitAny will unblock when one of the handles the current thread is waiting on transitions to the signaled state. There are several overloads of these methods, which let you specify timeouts in several formats.

The WaitOne and WaitAll methods return a boolean: you’ll get true when the methods return as a result of the object being signaled or false if it returns as a consequence of the timeout. WaitAny has a different behaviour because it returns an integer (which indicates the handle which was signaled and unblocked the thread). When a timeout occurs, WaitAny ends up returning the constant WaitHandle.WaitTimeout (258).

The next snippet tries to show how you can use the WaitAll method to wait on several kernel objects:

var evt1 = new AutoResetEvent(false);
var evt2 = new AutoResetEvent(false);
var evt3 = new AutoResetEvent(false);         
new Thread( () => {
    Console.WriteLine( "Thread {0}", Thread.CurrentThread.ManagedThreadId );
new Thread( () => {
    Console.WriteLine( "Thread {0}", Thread.CurrentThread.ManagedThreadId );
new Thread( () => {
    Console.WriteLine( "Thread {0}", Thread.CurrentThread.ManagedThreadId );
WaitHandle.WaitAll( new[]{ evt1, evt2, evt3 } );
Console.WriteLine("Ended wait");

Now, you could also change the code so that the main thread will only wait until one of the events gets signaled:

//previous code is the same
var pos = WaitHandle.WaitAny( new[] { evt1, evt2, evt3 });
Console.WriteLine("Ended wait. Evt in position {0} as signaled",pos);

In this case,you’ll get the position of the signaled kernel object in the array you’ve passed into the WaitAny method.

You should also keep in mind that you might end up getting exceptions when you call these methods (think abandoned mutexes and Interrupt calls!), so you’ll probably want to use them inside a try/catch block. As you can see, using these methods isn’t really that complicated. There’s still one very interesting method used for waiting that we still haven’t looked at: I’m talking about the SignalAndWait. We’ll talk about it in the next post.

~ by Luis Abreu on May 21, 2009.

Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: