Introduction
In my previous article we have discussed the following Synchronization techniques:
- lock : Ensures just one thread can access a resource, or section of code.
- Mutex : Ensures just one thread can access a resource, or section of code. Can be used to prevent multiple instances of an application from starting.
- Semaphore :Ensures not more than a specified number of threads can access a resource, or section of code.
In this article I will discribe a Must Inherit
type class,WaitHandle.
WaitHandle
provides a class definition for three other classes, Mutex , ManualResetEvent
and AutoResetEvent,
and provides means for your own objects to inherit synchronization
functionality. These objects allow threads to wait until classes derived from WaitHandle
are signaled. The WaitHandle derived classes add functionality over Monitor in that threads can be programmed
to wait until multiple classes are signaled. Of course, along with more power
and flexibility comes more work and chance of problems.
This acts like a turnstile (Moving Door) which lets one at a time. When a thread hits WaitOne(), it waits till some other thread calls set(). An AutoResetEvent gets reset automatically once the waiting thread observes the event is signalled (set). Apart from this being convenient if you are reusing the event multiple times, it has a practical application: if there are are multiple threads waiting on an auto-reset event, only one of them will wake up when the event gets set. As a waiting thread, if you observe that you have woken up because an auto-reset event you were waiting on became signalled, then you can know that no other thread waiting on that same event would have woken up.
The AutoResetEvent
class can be compared to the Monitor. Pulse
method. Imagine it as a tollbooth. Each car
has to pay to go through, the signal, and then the gate closes behind the car
when it es making the next car in line pay again. The AutoResetEvent
class is like this. It automatically goes back to unsignaled after being
signaled and a thread goes through, just like Monitor.
Pulse. ManualResetEvent
can be described as a water hose, once open it lets everything through until you
close it yourself.
AutoResetEvent allows threads to communicate with each other by signaling. Typically, this communication concerns a resource to which threads need exclusive access. We can control the initial state of an AutoResetEvent by ing a Boolean value to the constructor,true if the initial state is signaled and false otherwise.
AutoResetEvent can also be used with the static
I have put together a simple console application to demonstrate this class.
using
System;
using
System.Threading;
namespace
AutoResetEventIN
{
class Process
{
AutoResetEvent auto;
Process()
{
auto = new
AutoResetEvent(false);
Thread t1 =
new Thread(new
ThreadStart(akshay));
Thread t2 =
new Thread(new
ThreadStart(csharpcorner));
t1.Start();
t2.Start();
auto.Set();
Thread.Sleep(1000);
auto.Set();
}
void akshay()
{
auto.WaitOne();
for (int
i = 0; i < 10; i++)
{
Thread.Sleep(500);
Console.WriteLine("Akshay
Teotia");
}
}
void csharpcorner()
{
auto.WaitOne();
for (int
i = 0; i < 10; i++)
{
Thread.Sleep(500);
Console.WriteLine("csharpcorner.com");
}
}
static void
Main(string[] args)
{
Process p =
new Process();
Console.Read();
}
}
}
Output

ManualResetEvent
ManualResetEvent allows threads to communicate with each other by signaling. Typically, this communication concerns a task which one thread must complete before other threads can proceed. This is like a gate which lets more than one at a time. When a thread hits WaitOne(), it waits till someother thread calls Set().
A ManualResetEventis useful if you want to wake up a bunch of threads with a single event. It's useful for things like termination events where you don't want to reset the event just because you observed it signalled. If the meaning of the event is more like a flag, then you can observe the flag without changing its state back to unsignalled.
When a thread begins an activity that must complete before other threads proceed, it calls Reset to put ManualResetEvent in the non-signaled state. This thread can be thought of as controlling the ManualResetEvent. Threads that call WaitOne() on the ManualResetEvent will block, awaiting the signal. When the controlling thread completes the activity, it calls Set to signal that the waiting threads can proceed. All waiting threads are released.
Once it has been signaled, ManualResetEvent remains signaled until it is manually reset. That is, calls to WaitOne()return immediately. Like AutoResetEvent we can control the initial state of the ManualResetEvent by ing a Boolean value to the constructor, true if the initial state is signaled and false otherwise.
ManualResetEvent can also be used with the static WaitAll() and WaitAny() methods.
I have put together a simple console application to demonstrate this class.
using
System;
using
System.Threading;
namespace
ManualResetEventIn
{
class MyThread
{
public
Thread th;
ManualResetEvent manualResetEvent;
public MyThread(string
name, ManualResetEvent e)
{
th = new
Thread(this.run);
th.Name = name;
manualResetEvent = e;
th.Start();
}
void run()
{
Console.WriteLine("Inside
thread " + th.Name);
for (int
i = 0; i < 10; i++)
{
Console.WriteLine(th.Name);
Thread.Sleep(50);
}
Console.WriteLine(th.Name +
" Done!");
manualResetEvent.Set();
}
}
class MainClass
{
public static
void Main()
{
ManualResetEvent evtObj =
new ManualResetEvent(false);
MyThread myThread =
new MyThread("Event
Thread 1", evtObj);
Console.WriteLine("Main
thread waiting for event.");
// Wait for signaled event.
evtObj.WaitOne();
Console.WriteLine("Main
thread received first event.");
evtObj.Reset();
myThread = new
MyThread("Event
Thread 2", evtObj);
// Wait for signaled event.
evtObj.WaitOne();
Console.WriteLine("Main
thread received second event.");
Console.Read();
}
}
}
Output


Join the conversation! Your thoughts help the community grow.