Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What does AutoResetEvent.Set() do ?

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 

?

like image 713
JAN Avatar asked Oct 09 '15 11:10

JAN


3 Answers

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

like image 167
Jon Hanna Avatar answered Nov 16 '22 02:11

Jon Hanna


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.

like image 4
Groo Avatar answered Nov 16 '22 04:11

Groo


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.

  • https://msdn.microsoft.com/en-us/library/system.threading.autoresetevent(v=vs.110).aspx
like image 3
sab669 Avatar answered Nov 16 '22 02:11

sab669