What does AutoResetEvent.Set() do ?
Asked Answered
P

5

13

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 

?

Paw answered 9/10, 2015 at 11:41 Comment(3)
It sends a signal to all waiting threads.Tribalism
@Tribalism No, it signals only one thread. Remember this is an AutoResetEventCento
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.Fairman
D
17

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

Depoliti answered 9/10, 2015 at 12:14 Comment(0)
B
5

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.

Bugeye answered 9/10, 2015 at 23:31 Comment(0)
A
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.

Artair answered 9/10, 2015 at 11:43 Comment(0)
M
1

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

Masturbate answered 9/10, 2015 at 11:44 Comment(3)
Then what is the initial state for ? You put a true or false , for what ?Paw
Good explanations here - but the quick answer is that the first waiter gets through. #13719786Pyrites
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.Masturbate
M
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.

Mathison answered 9/10, 2015 at 12:4 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.