11

If I do this :

private static System.Threading.AutoResetEvent event_2 = new System.Threading.AutoResetEvent(false);

And then in Main thread I do :

event_2.Set();

It changes the state from false to true ?

If so , it basically does :

AutoResetEventState = !AutoResetEventState 

?

JAN
  • 21,236
  • 66
  • 181
  • 318
  • 1
    It sends a signal to all waiting threads. – kevintjuh93 Oct 09 '15 at 11:43
  • 4
    @kevintjuh93 No, it signals only one thread. Remember this is an `AutoResetEvent` – Sriram Sakthivel Oct 09 '15 at 12:02
  • 1
    The Set() event makes a tree drop in the forest. If there is nobody around to hear it by calling WaitOne() then it doesn't make a sound. Otherwise a very basic thread synchonization primitive, only ManualResetEvent is easier to understand. – Hans Passant Oct 09 '15 at 23:57

5 Answers5

14

It sets the state to one that allows threads to continue execution if they Wait() on it.

If there are any threads already waiting, then one will be allowed to progress and the state will immediately be set to not set, so all other threads will continue to block.

If there are no threads currently waiting then the first to wait will immediately be allowed through, but subsequent threads will block.

The same general mechanism is shared by other EventWaitHandle-derived classes, but the automatic resetting upon a thread being allowed to progress is different to ManualResetEvent, hence the names.

The initial state is signalled (allowing threads to progress) if true is passed to the constructor, and not signalled if false is passed, so passing true is the same as if you'd called Set() immediately after construction while passing false is conversely the same as if you'd called Reset().

Jon Hanna
  • 110,372
  • 10
  • 146
  • 251
4

To add to other answers, the reason you need a this (instead of having a bool property you would simply toggle) is:

  1. Signalling: threads which are blocked at e.WaitOne() will be signalled, and one of them will continue. If you wanted to do this yourself without synchronization primitives, you would have to implement some sort of polling; a "blocking" thread would have to poll a bool (or, say, int) field in regular intervals to check if it has changed and it is allowed to continue. If nothing else, this would unnecessarily consume cpu cycles and would have a delay (depending on your polling interval).

  2. Atomicity: if multiple threads are waiting, you have a guarantee only one will be unblocked. Ensuring the same behavior using the mentioned polling solution would require use of locking or atomic instructions (like the ones found in Interlocked class) and good understanding of possible compiler and processor instruction reordering/memory barriers.

If you are looking for a simple way to synchronize multiple threads, this is one of the simplest (if not the simplest) solutions in .NET. Creating a producer/consumer queue is remarkably simple:

// Simplified example. Check http://www.albahari.com/threading/part2.aspx
// for detailed explanations of this and other syncronizing constructs

private readonly AutoResetEvent _signal = new AutoResetEvent(false);
private readonly ConcurrentQueue<Something> _queue = new ConcurrentQueue<Something>();

// this method can be called by one or more threads simultaneously
// (although the order of enqueued items cannot be known if many threads are competing)
void ProduceItem(Something s)
{
    _queue.Enqueue(s);  // enqueue item for processing
    _signal.Set();      // signal the consumer thread if it's waiting
}

// this loop should be running on a separate thread.
void ConsumerLoop()
{
    while (!_ending)
    {
        // block until producer signals us
        _signal.WaitOne();

        // process whatever is enqueued 
        Something s = null;
        while (!_ending && _concurrentQueue.TryDequeue(out s))
        {
             Process(s);
        }
    }
}

One thing you need to keep in mind though is that multiple successive calls to Set won't necessarily signal WaitOne multiple times. In this example, several producers might fire the Set method, but it may take a couple of milliseconds until the context switch happens and ConsumerLoop continues, meaning that only a single Set will effectively get processed.

vgru
  • 49,838
  • 16
  • 120
  • 201
3

A thread waits for a signal by calling WaitOne on the AutoResetEvent. If the AutoResetEvent is in the non-signaled state, the thread blocks, waiting for the thread that currently controls the resource to signal that the resource is available by calling Set.

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 non-signaled state. If no threads are waiting, the state remains signaled indefinitely.

Community
  • 1
  • 1
sab669
  • 3,984
  • 8
  • 38
  • 75
1

It another thread is waiting for event using event_2.Wait() and you call .Set() from your thread, waiting thread will continue execution.

dlxeon
  • 1,932
  • 1
  • 11
  • 14
  • Then what is the initial state for ? You put a `true` or `false` , for what ? – JAN Oct 09 '15 at 11:44
  • Good explanations here - but the quick answer is that the first waiter gets through. http://stackoverflow.com/questions/13719286/new-autoresetevent-true-usages-in-c – Robert Horvick Oct 09 '15 at 11:46
  • Initial state "true" makes sense if you want that another thread will run immediately without waiting. Alternative is to create AutoResetEvent and then immediately call .Set() to it. – dlxeon Oct 09 '15 at 11:47
0

If so , it basically does :

AutoResetEventState = !AutoResetEventState

?

In addition to that it also sets the EventWaitHandle to signaling state allowing one or more thread to proceed.

Fabjan
  • 13,506
  • 4
  • 25
  • 52