简体   繁体   中英

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 

?

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

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.

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.

另一个线程正在使用event_2.Wait()等待事件,并从线程调用.Set(),等待线程将继续执行。

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM