Differencebetween Manualresetevent and Autoresetevent in .Net

What is the difference between ManualResetEvent and AutoResetEvent in .NET?

Yes. It's like the difference between a tollbooth and a door. The ManualResetEvent is the door, which needs to be closed (reset) manually. The AutoResetEvent is a tollbooth, allowing one car to go by and automatically closing before the next one can get through.

Auto- vs ManualResetEvent, differences

The difference is in what happens when the event is signaled (set).

  • the manual-reset event will stay signaled until your explicitly reset it again
  • the auto-reset event will automatically get reset (unsignaled) once the first thread waiting for it gets awaken

In general I find it easier to work with manual reset events because in most cases it is a bit more straight-forward to determine the state of the event at any given time.

That said there are cases when the behavior of the auto-reset event lends itself better to achieving synchronization because you are guaranteed that only one of the waiting threads will be signaled. So if you have a producer/multiple-consumers scenario where any, but only, one consumer should be signaled you should consider the auto-reset event.

AutoResetEvent, ManualResetEvent vs Monitor

If you can, go with Monitor. It's similar to a CRITICAL_SECTION. AutoResetEvent/ManualResetEvent might have slightly more overhead, since these can be shared by different processes, whereas a Monitor belongs to a single process.

autoresetevent and manualresetevent

There are a few places where this sort of thing is used. Personally I usually prefer Monitor.Wait/Pulse, but there are times when {Manual/Auto}ResetEvent is more useful - particularly where you want to be able to wait on multiple handles.

The two most obvious cases where I've seen this used are:

  • Producer/consumer queues: when the queue is empty, the consumer will wait on a monitor or wait handle. The producer will then pulse/set the monitor/handle when it's added an item, to wake up the consumer so it knows it has work to do.
  • Waking up a "sleeping" thread to let it know that it can exit: it's not unusual to have a while(!ShouldStop) { Work(); Wait(10000); } sort of loop; the "stopping" thread can again make the waiting thread wake up notice that the "stop" flag has been set

These are quite similar scenarios of course, and no doubt there are more - but those are the ones I've seen most often.

When would I use AutoResetEvent and ManualResetEvent instead of Monitor.Wait()/Monitor.Pulse()?

Use the events when you've got a thread that is waiting on one of or all of a number of events to do something.

Use the monitor if you want to restrict access to a data structure by limiting how many threads can access it.

Monitors usually protect a resource, whereas events tell you something's happening, like the application shutting down.

Also, events can be named (see the OpenExisting method), this allows them to be used for synchronization across different processes.

Whats is the difference between AutoResetEvent and Mutex

Different concept - a Mutex is an exclusive token; only one person can have it; when they release it, somebody else can fight over it. An AutoResetEvent is a gate that allows exactly one person through before closing, and which is operated by a button that is separate to the queue of people wanting to go through. When they pass through the gate immediately closes.

Is there any difference between an AutoResetEvent and a Semaphore with maximumCount = 1?

Yes, there certainly is a difference. A Semaphore is used to throttle access to a resource or block of code. When WaitOne is called a thread will block until a count from the semaphore becomes available. To make a count availabe you would call Release. A semaphore with a maximum count of 1 is often called a binary semaphore. A semaphore of this nature only allows access to a resource or block code from a single thread. You could use a binary semaphore in place of a mutex or monitor. The important thing to remember about the Semaphore is that its state is manually controlled via calls to WaitOne and Release.

An AutoResetEvent on the other hand is primarily used as a signaling mechanism. One thread will block via a call to WaitOne waiting for a signal. Another thread will call Set to initiate that signal. An ARE publishes this signal to one and only one thread and then immediately resets the ARE to an unsignaled state. The important thing to remember about the AutoResetEvent is that it is manually signaled via a call to Set and automatically reset after when a single call to WaitOne returns.

So here is a summary of differences:

  • A Semaphore's state is manually controlled.
  • A AutoResetEvent's state is manually set, but automatically reset.
  • With a Semaphore threads typically balance the Release and WaitOne calls.
  • With a AutoResetEvent one thread is typically designated as the signaler and another is the waiter.
  • A Semaphore throttles access to a resource or block of code.
  • A AutoResetEvent signals a thread to take some action.

Think of a AutoResetEvent as a door to a hallway. The door will allow one and only one person through the door after receiving a command to do so. Once a person goes through the door it immediately closes and waits for another command. As long as the door keeps receiving new commands the hallway is free to fill with as many people as the number of commands given.

Think of a Semaphore as a door to the same hallway. The door will allow a certain number of people in the hallway. The door remains open until the hallway reaches its occupancy limit at which time the door closes. After someone leaves the hallway through the other side then this door opens again.

Update:

Here is the simplest possible example that demonstrates that something is clearly different.

static void Main()
{
var are = new AutoResetEvent(false);
are.Set();
are.Set();

var semaphore = new Semaphore(0, 1);
semaphore.Release();
semaphore.Release();
}

It comes as no surprise that you will get an exception on the second semaphore.Release call whereas the second call to Set passes through just fine. The reason is because an ARE is setting a boolean flag whereas the semaphore is attempting to increase the count.

The WaitOne methods will work the same way, but the Release and Set methods will not. It is for this reason that a binary semaphore is not interchangable with an ARE. However, an ARE could be interchangable with a binary semaphore in some cases.

One scenario where there is overlap is in the case of a latch for a single thread.

public static void Main()
{
var latch = new AutoResetEvent(false);

new Thread(
() =>
{
latch.WaitOne(); // Wait for the latch.
}).Start();

latch.Set(); // Release the latch.
}

Here is a scenario that can only be satisfied by a AutoResetEvent.

static void Main()
{
var are = new AutoResetEvent(false);

new Thread(
() =>
{
while (true)
{
are.WaitOne();
Console.WriteLine("go");
Thread.Sleep(2000);
}
}).Start();

while (true)
{
are.Set();
Console.WriteLine("pulse");
Thread.Sleep(1000);
}

}

Why AutoResetEvent and ManualResetEvent does not support name in the constructor?

You can make a named manual reset event like so:

// Open the event by name.
EventWaitHandle namedMRSE =
new EventWaitHandle(false, EventResetMode.ManualReset, @"TheName");

Here is the reference for the above code. I don't know of the particular reason behind the design, but there are some notes on msdn that suggest there is a distinction based on the application domain and the process:

Event wait handles are useful in many
of the same synchronization scenarios
as the Monitor class. Event wait
handles are often easier to use than
the System.Threading.Monitor.Wait and
System.Threading.Monitor.Pulse(System.Object)
methods, and they offer more control
over signaling. Named event wait
handles can also be used to
synchronize activities across
application domains and processes,
whereas monitors are local to an
application domain.



Related Topics



Leave a reply



Submit