Sign up ×
Stack Overflow is a question and answer site for professional and enthusiast programmers. It's 100% free.

I have read the documentation on this and I think I understand. An AutoResetEvent resets when the code passes through event.WaitOne(), but a ManualResetEvent does not.

Is this correct?

share|improve this question

8 Answers 8

up vote 488 down vote accepted

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.

share|improve this answer
79  
That is a great analogy. –  twk Sep 30 '08 at 17:04
2  
@Dan very good understanding. –  balaweblog Dec 16 '08 at 13:11
7  
Or like a door and a turnstile. –  Constantin Jan 6 '09 at 19:01
5  
tollbooth and a door analogy...too good. –  P.K Aug 11 '09 at 10:14
5  
Oh, that's why they are named what they are. –  Arlen Beiler Oct 5 '12 at 11:09

Just imagine that the AutoResetEvent executes WaitOne() and Reset() as a single atomic operation.

share|improve this answer

The short answer is yes. The most important difference is that an AutoResetEvent will only allow one single waiting thread to continue. A ManualResetEvent on the other hand will keep allowing threads, several at the same time even, to continue until you tell it to stop (Reset it).

share|improve this answer

Taken from C# 3.0 Nutshell book, by Joseph Albahari

Threading in C# - Free E-Book

A ManualResetEvent is a variation on AutoResetEvent. It differs in that it doesn't automatically reset after a thread is let through on a WaitOne call, and so functions like a gate: calling Set opens the gate, allowing any number of threads that WaitOne at the gate through; calling Reset closes the gate, causing, potentially, a queue of waiters to accumulate until its next opened.

One could simulate this functionality with a boolean "gateOpen" field (declared with the volatile keyword) in combination with "spin-sleeping" – repeatedly checking the flag, and then sleeping for a short period of time.

ManualResetEvents are sometimes used to signal that a particular operation is complete, or that a thread's completed initialization and is ready to perform work.

share|improve this answer

Yes, thats right.

You can get an idea by the usage of these two.

If you need to tell that you are finished with some work and other (threads) waiting for this can now proceed, you should use ManualResetEvent.

If you need to have mutual exclusive access to any resource, you should use AutoResetEvent.

share|improve this answer

I created simple examples to clarify understanding of ManualResetEvent vs AutoResetEvent.

AutoResetEvent: lets assume you have 3 workers thread. If any of those threads will call WaitOne() all other 2 threads will stop execution and wait for signal. I am assuming they are using WaitOne(). It is like; if I do not work, nobody works. In first example you can see that

            autoReset.Set();
            Thread.Sleep(1000);
            autoReset.Set();

When you call Set(); all threads will work and wait for signal. After 1 sec I am sending second signal and they execute and wait (WaitOne();). Think about these guys are soccer team players and if one player says I will wait until manager calls me, and others will wait until manager tells them to continue (Set();)

public class AutoResetEventSample
    {
        private AutoResetEvent autoReset = new AutoResetEvent(false);

        public void RunAll()
        {
            new Thread(Worker1).Start();
            new Thread(Worker2).Start();
            new Thread(Worker3).Start();
            autoReset.Set();
            Thread.Sleep(1000);
            autoReset.Set();
            Console.WriteLine("Main thread reached to end.");
        }

        public void Worker1()
        {
            Console.WriteLine("Entered in worker 1");
            for (int i = 0; i < 5; i++)
            {
                Console.WriteLine("Worker1 is running {0}", i);
                Thread.Sleep(2000);
                autoReset.WaitOne();
            }
        }
        public void Worker2()
        {
            Console.WriteLine("Entered in worker 2");

            for (int i = 0; i < 5; i++)
            {
                Console.WriteLine("Worker2 is running {0}", i);
                Thread.Sleep(2000);
                autoReset.WaitOne();
            }
        }
        public void Worker3()
        {
            Console.WriteLine("Entered in worker 3");

            for (int i = 0; i < 5; i++)
            {
                Console.WriteLine("Worker3 is running {0}", i);
                Thread.Sleep(2000);
                autoReset.WaitOne();
            }
        }
    }

In this example you can clearly see that when you first hit Set(); it will let all threads go, then after 1 sec it signals all threads to wait! As soon as you set them again regardless they are calling WaitOne() inside, they will keep running because you have to manually call Reset() to stop them all.

            manualReset.Set();
            Thread.Sleep(1000);
            manualReset.Reset();
            Console.WriteLine("Press to release all threads.");
            Console.ReadLine();
            manualReset.Set();

It is more about Referee/Players relationship there regardless of any of the player is injured and wait for playing others will continue to work. If Referee says wait (Reset();) then all players will wait until next signal.

    public class ManualResetEventSample
    {
        private ManualResetEvent manualReset = new ManualResetEvent(false);

        public void RunAll()
        {
            new Thread(Worker1).Start();
            new Thread(Worker2).Start();
            new Thread(Worker3).Start();
            manualReset.Set();
            Thread.Sleep(1000);
            manualReset.Reset();
            Console.WriteLine("Press to release all threads.");
            Console.ReadLine();
            manualReset.Set();
            Console.WriteLine("Main thread reached to end.");
        }

        public void Worker1()
        {
            Console.WriteLine("Entered in worker 1");
            for (int i = 0; i < 5; i++)
            {
                Console.WriteLine("Worker1 is running {0}", i);
                Thread.Sleep(2000);
                manualReset.WaitOne();
            }
        }
        public void Worker2()
        {
            Console.WriteLine("Entered in worker 2");

            for (int i = 0; i < 5; i++)
            {
                Console.WriteLine("Worker2 is running {0}", i);
                Thread.Sleep(2000);
                manualReset.WaitOne();
            }
        }
        public void Worker3()
        {
            Console.WriteLine("Entered in worker 3");

            for (int i = 0; i < 5; i++)
            {
                Console.WriteLine("Worker3 is running {0}", i);
                Thread.Sleep(2000);
                manualReset.WaitOne();
            }
        }
    }
share|improve this answer

Yes. This is absolutely correct.

You could see ManualResetEvent as a way to indicate state. Something is on (Set) or off (Reset). An occurrence with some duration. Any thread waiting for that state to happen can proceed.

An AutoResetEvent is more comparable to a signal. A one shot indication that something has happened. An occurrence without any duration. Typically but not necessarily the "something" that has happened is small and needs to be handled by a single thread - hence the automatic reset after a single thread have consumed the event.

share|improve this answer

autoResetEvent.WaitOne()

is equal to

try
{
   manualResetEvent.WaitOne();
}
finally
{
   manualResetEvent.Reset();
}
share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.