J M
J M

Reputation: 1901

Why does the second thread get released before the first one, when they both called WaitOne() and were released by an AutoResetEvent?

Suppose that ThreadA and ThreadB both call WaitOne() in that order on the same AutoResetEvent. When the event is set, why does ThreadB get released instead of ThreadA?

I ran a test to find out what happens when you set an AutoResetEvent on which mutiple threads are waiting:

    private static void Test()
    {
        // two threads - waiting for the same autoreset event
        // start it unset i.e. closed i.e. anything calling WaitOne() will block
        AutoResetEvent autoEvent = new AutoResetEvent(false);

        Thread thread1 = new Thread(new ThreadStart(WriteSomeMessageToTheConsole));
        thread1.Start();  // this will now block until we set the event

        Thread thread2 = new Thread(new ThreadStart(WriteSomeOtherMessageToTheConsole));
        thread2.Start();  // this will now also block until we set the event

        // simulate some other stuff
        Console.WriteLine("Doing stuff...");
        Thread.Sleep(5000);
        Console.WriteLine("Stuff done.");

        // set the event - I thought this would mean both waiting threads are allowed to continue
        // BUT thread2 runs and thread1 stays blocked indefinitely
        // So I guess I was wrong and that Set only releases one thread in WaitOne()?
        // And why thread2 first?
        autoEvent1.Set();
    }

The code is of course not useful, it's just a simple example.

Upvotes: 2

Views: 2602

Answers (3)

D.Shawley
D.Shawley

Reputation: 59633

IIRC, which thread is released by an auto-reset event is unspecified. As everyone else mentioned, you want a manual reset event if you want to broadcast a condition. If you want to release an exact number (say exactly 3 of n), then you probably want to use a semaphore.

If you really want to dig into why the order might be different than you would expect, take a look at "Windows Internals" or anything that Mark Russinovich has written. Chances are that he explains the wait order on executive resources somewhere.

Upvotes: 2

J.W.
J.W.

Reputation: 18181

From MSDN

MSDN on 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.

But for AutoResetEvent, MSDN says: "Calling Set signals AutoResetEvent to release a waiting thread. AutoResetEvent remains signaled until a single waiting thread is released, and then automatically returns to the nonsignaled state. If no threads are waiting, the state remains signaled indefinitely.

"

Upvotes: 2

JP Alioto
JP Alioto

Reputation: 45127

On an AutoResetEvent, Set only releases one thread. You should use a ManualResetEvent to release multiple waiting threads.

Upvotes: 0

Related Questions