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
?
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()
.
To add to other answers, the reason you need a this (instead of having a bool
property you would simply toggle) is:
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).
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.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With