Multithreading: using AutoResetEvents

After the introductory theory associated with events, it’s time to take a look at how we can use an AutoResetEvent for synchronizing access to a protected resource. The first thing we need to do to start using an AutoResetEvent is getting a reference to a valid instance of this type. We can get one by calling one of the constructors or one of the several overloads of the OpenExisting method:

//create new
public EventWaitHandle(bool initialState, EventResetMode mode);
public EventWaitHandle(bool initialState, EventResetMode mode, string name);
public EventWaitHandle(bool initialState, EventResetMode mode, string name, out bool createdNew);
public EventWaitHandle(bool initialState, EventResetMode mode, string name, out bool createdNew, EventWaitHandleSecurity eventSecurity);

//get valid reference for existing event
public static EventWaitHandle OpenExisting(string name);
public static EventWaitHandle OpenExisting(string name,EventWaitHandleRights rights);

As we’ve seen,AutoResetEvent don’t have the concept of ownership. This means that one thread can Set the event and another Reset it. Take a look at the following code:

var evt = new AutoResetEvent(false);//not signaled
new Thread(() => {
                     evt.WaitOne();
                     Console.WriteLine("Entered thread1");
                     evt.Set();
                 }).Start();
new Thread(() => {
                    evt.WaitOne();
                    Console.WriteLine("Entered thread2");
                    evt.Set();
                }).Start();
Console.WriteLine("Fired threads");
Thread.Sleep(200);
new Thread(() =>{ evt.Set();}).Start();
Console.ReadLine();

Granted: this doesn’t really do anything useful, but it shows how things work when you use an event. As you can see, we start by creating a new AutoResetEvent which is in the non-signaled state. That means that the two new created threads will block until the main thread wakes up and starts another thread, which is responsible for setting the event (and allowing the wakening of one of those blocked threads).

By setting event, the AutoResetEvent will transition *automatically* to the non signaled after another waiting thread is waken up and starts doing its work (ie, you don’t have to call Reset for it to go back to the non-signaled state).

Joe Duffy points out an important detail about events and priority boosts. According to Joe, a thread that is waiting on an event sees its priority boosted to 1 whenever it is wakened. Generally, this is ok, but it might lead to some undesired scenarios where the thread that sets the event holds to a resource that the waiting thread will need.

So, as you can see, using an AutoResetEvent isn’t really that difficult from using the other kernel objects we’ve met in previous posts: first you need to get a reference by creating a new object or getting a reference to a previously named object; then you wait on it by calling one of the WaitXXX methods; finally, you allow another thread to wake up and do its work by signaling the object through a Set method call.

On the next post, we’ll take a look at the ManualResetEvent class. Keep tuned.

Advertisements

~ by Luis Abreu on May 18, 2009.

Leave a Reply

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

WordPress.com Logo

You are commenting using your WordPress.com 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: