Thread Synchronization Using Reset Events in .NET Framework

Introduction

In this article I will explain about the reset events in the .NET framework. I have chosen to write on this topic as I felt this part is always little confusing for developers. The reset events are the wait handles, which helps in synchronizing threads in the middle of some asynchronous threading operations where multiple threads are executing simultaneously.

Multi-Threading and Thread Synchronization

Multi-Threading is an operation where multiple threads can be spawned in a process after which the processing load can be divided and handed over to each thread. This helps in improving the performance of the application while doing lengthy, data processing intense or time consuming processes.

While doing a multi-threading operation, different threads can be accessing the same resource (shared resource - non thread safe) at the same time; such a situation would lead to a dead lock, racing or undesired behaviors. In order to avoid such nightmare situations in the thread, synchronization is required.

Reset Event Handles in .NET Framework

In the .NET framework there are many techniques to perform thread synchronization, such as lock, monitor, etc. Reset event wait handles are one among them. There are two kinds of reset event wait handles.

1. AutoResetEvent

2. ManualResetEvent

Using the above mentioned wait handles you can make the spawned threads to wait indefinitely until they are signaled in occurrence of an event. Below are some important methods of the reset events and their explanations.

1. WaitOne - Makes all the spawned threads wait indefinitely until they are signaled. It also has an overload where you can set the maximum time in milliseconds until which the threads can wait.

2. Set - This method is used to signal the thread to continue with the processing.

3. Reset - This method is used to un-signal the threads.

Difference Between AutoResetEvent and ManualResetEvent

Now a question may rise, why are two different wait handles required? Here is the difference.

AutoResetEvent:

1. Once signaled only one thread is released.

2. Reset happens automatically after the thread is released.

ManualResetEvent:

1. Once signaled all the threads are released.

2. Reset should be manually done using the Reset method of the wait handle. Until the threads are explicitly un-signaled they will not wait on the Wait methods.

Choosing Between AutoResetEvent and ManualResetEvent

Many developers, even though they have knowledge of the reset event wait handles, still struggle to choose between the two. Here is a simple explanation.

If the threads executing a particular method should be synchronized so that the method resource is accessed by one thread at a time, then use AutoResetEvent. If all the threads should wait for an event to be completed by another thread and can start processing simultaneously after the event is occurred, then go for ManualResetEvent.

Sample Code

In this section I have provided the sample console application code and an explanation of the behavior of the two different wait handles. Below is the code using the AutoResetEvent.

class Program
{
   static AutoResetEvent _autoResetEvent = new AutoResetEvent(false);
   static void Main(string[] args)
   {
     Thread thread1 = new Thread(new ParameterizedThreadStart(PrintNames));
     thread1.Name = "Thread1";
     thread1.Start("Simon");
     Console.WriteLine("Thread1 invoked");
     Thread thread2 = new Thread(new ParameterizedThreadStart(PrintNames));
     thread2.Name = "Thread2";
     thread2.Start("Bear Grylls");
     Console.WriteLine("Thread2 invoked");
     Thread thread3 = new Thread(new ParameterizedThreadStart(PrintNames));
     thread3.Name = "Thread3";
     thread3.Start("Les Stroud");
     Console.WriteLine("Thread3 invoked");
     Console.WriteLine("All the three threads are waiting in AddNames function!");
     //Release the first thread and let it take care of releasing the rest
     _autoResetEvent.Set();
     Console.ReadLine();
    }
    static void PrintNames(object name)
    {
     //Do some processing
     //Make all the incoming threads wait until it is signaled.
     _autoResetEvent.WaitOne();
     Console.WriteLine("{0} released!", Thread.CurrentThread.Name);
     Console.WriteLine("Name given: {0}", name);
     //Release the next thread
     _autoResetEvent.Set();
    }
}

Now run the application and the output is shown in Fig 1.0.

Figure 1
Fig 1.0

From Fig 1.0 you can see that using the auto reset event signaling releases the threads one after the other and this releasing order is not in sequence.

Modify the code a little to use the ManualResetEvent as shown below.

class Program
{
  static ManualResetEvent _manualResetEvent = new ManualResetEvent(false);
 
  static void Main(string[] args)
  {
    Thread thread1 = new Thread(new ParameterizedThreadStart(PrintNames));
    thread1.Name = "Thread1";
    thread1.Start("Simon");
    Console.WriteLine("Thread1 invoked");
    Thread thread2 = new Thread(new ParameterizedThreadStart(PrintNames));
    thread2.Name = "Thread2";
    thread2.Start("Bear Grylls");
    Console.WriteLine("Thread2 invoked");
    Thread thread3 = new Thread(new ParameterizedThreadStart(PrintNames));
    thread3.Name = "Thread3";
    thread3.Start("Les Stroud");
    Console.WriteLine("Thread3 invoked");
    Console.WriteLine("All the three threads are waiting in AddNames function!");
 
    //Release the first thread and let it take care of releasing the rest
    _manualResetEvent.Set();
 
    Console.ReadLine();
  }
 
  static void PrintNames(object name)
  {
    //Do some processing
    //Make all the incoming threads wait until it is signaled.
    _manualResetEvent.WaitOne();
    Console.WriteLine("{0} released!", Thread.CurrentThread.Name);
//Try making the threads wait again. This will not succeed as an explicit reset is required for ManualResetEvent
    _manualResetEvent.WaitOne();
    Console.WriteLine("Name given: {0}", name);
  }
}

Run the application and Fig 1.1 is the output window.

Figure 1.1
Fig 1.1

Notice that all the threads are released in a single signal and also the second WaitOne is not effective as the ManualResetEvent should be reset manually after it is signaled.

Conclusion

Hope this article has explained about the wait handles and using them appropriately based on the situation. Please make use of the comments section to put in your comments.

Happy Reading!



Related Articles

Comments

  • wheloltabotly PumeSonee Phobereurce 9945935

    Posted by TizefaTaNaday on 06/10/2013 03:37pm

    sourhoozy airjordanretrosreleasedates2012.holidaygiving.org Nuadbasia airjordanretro3whitefirered.holidaygiving.org Loosecoichory

    Reply
  • URL REDIRECTION

    Posted by anil on 08/01/2012 11:30pm

    What is URL REDIRECTION?How can i use this concept in my .net? my task is i have generated one url like this "http://example.com/" I am passing one pearameter like "http://example.com/Empno=1" I want to display Ename in Database table that corresponding "Empno" plz Help me Give me one simple exampleI am new this concepts plz Help me

    Reply
Leave a Comment
  • Your email address will not be published. All fields are required.

Top White Papers and Webcasts

  • Live Event Date: November 20, 2014 @ 2:00 p.m. ET / 11:00 a.m. PT Are you wanting to target two or more platforms such as iOS, Android, and/or Windows? You are not alone. 90% of enterprises today are targeting two or more platforms. Attend this eSeminar to discover how mobile app developers can rely on one IDE to create applications across platforms and approaches (web, native, and/or hybrid), saving time, money, and effort and introducing apps to market faster. You'll learn the trade-offs for gaining long …

  • IBM Worklight is a mobile application development platform that lets you extend your business to mobile devices. It is designed to provide an open, comprehensive platform to build, run and manage HTML5, hybrid and native mobile apps.

Most Popular Programming Stories

More for Developers

Latest Developer Headlines

RSS Feeds