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