如果我这样做:
private static System.Threading.AutoResetEvent event_2 = new System.Threading.AutoResetEvent(false);
然后在主线程中我做:
event_2.Set();
它将状态从 更改false
为true
?
如果是这样,它基本上是:
AutoResetEventState = !AutoResetEventState
?
如果我这样做:
private static System.Threading.AutoResetEvent event_2 = new System.Threading.AutoResetEvent(false);
然后在主线程中我做:
event_2.Set();
它将状态从 更改false
为true
?
如果是这样,它基本上是:
AutoResetEventState = !AutoResetEventState
?
它将状态设置为允许线程在其Wait()
上继续执行的状态。
如果有任何线程已经在等待,那么将允许其中一个线程继续进行并且状态将立即设置为未设置,因此所有其他线程将继续阻塞。
如果当前没有线程在等待,那么第一个等待的线程将立即被允许通过,但后续线程将阻塞。
其他派生类共享相同的通用机制EventWaitHandle
,但是允许线程进行时的自动重置与 不同ManualResetEvent
,因此名称不同。
如果传递给构造函数,则初始状态会发出信号(允许线程继续进行),如果true
传递则不会发出信号false
,因此传递与您在构造后立即true
调用相同,而传递则与您相反称为。Set()
false
Reset()
要添加到其他答案,您需要 this (而不是拥有bool
您只需切换的属性)的原因是:
发信号:被阻塞的线程e.WaitOne()
将被发信号,其中一个将继续。如果您想在没有同步原语的情况下自己执行此操作,则必须实现某种轮询;“阻塞”线程必须定期轮询bool
(或者说, )字段以检查它是否已更改并允许继续。int
如果不出意外,这将不必要地消耗 cpu 周期并且会有延迟(取决于您的轮询间隔)。
原子性:如果有多个线程在等待,你可以保证只有一个线程会被解锁。使用上述轮询解决方案确保相同的行为将需要使用锁定或原子指令(如类中的指令Interlocked
)以及对可能的编译器和处理器指令重新排序/内存屏障的良好理解。
如果您正在寻找一种同步多个线程的简单方法,这是 .NET 中最简单(如果不是最简单)的解决方案之一。创建生产者/消费者队列非常简单:
// 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);
}
}
}
不过,您需要记住的一件事是,多次连续调用Set
不一定会发出WaitOne
多次信号。在此示例中,多个生产者可能会触发该Set
方法,但在上下文切换发生并继续之前可能需要几毫秒ConsumerLoop
,这意味着只有一个生产者会Set
得到有效处理。
线程通过调用 AutoResetEvent 上的 WaitOne 来等待信号。如果 AutoResetEvent 处于非信号状态,则线程阻塞,等待当前控制资源的线程通过调用 Set 发出资源可用的信号。
调用 Set 发出 AutoResetEvent 信号以释放等待线程。AutoResetEvent 保持有信号状态,直到释放单个等待线程,然后自动返回到无信号状态。如果没有线程在等待,则状态会无限期地保持信号状态。
如果是这样,它基本上是:
AutoResetEventState = !AutoResetEventState
?
除此之外,它还设置了EventWaitHandle
信号状态,允许一个或多个线程继续进行。
另一个线程正在使用 event_2.Wait() 等待事件,并且您从线程中调用 .Set() ,等待线程将继续执行。