AutoResetEvent.Set() 是做什么的?
What does AutoResetEvent.Set() do ?
如果我这样做:
private static System.Threading.AutoResetEvent event_2 = new System.Threading.AutoResetEvent(false);
然后在主线程中我做:
event_2.Set();
它将状态从 false
更改为 true
?
如果是这样,基本上是这样:
AutoResetEventState = !AutoResetEventState
?
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.
如果另一个线程正在使用 event_2.Wait() 等待事件并且您从您的线程调用 .Set() ,等待线程将继续执行。
If so , it basically does :
AutoResetEventState = !AutoResetEventState
?
除此之外,它还将 EventWaitHandle
设置为信号状态,允许一个或多个线程继续进行。
它将状态设置为允许线程在 Wait()
上继续执行的状态。
如果有任何线程已经在等待,那么将允许一个线程继续进行并且状态将立即设置为未设置,因此所有其他线程将继续阻塞。
如果当前没有线程在等待,那么将立即允许第一个等待的线程通过,但后续线程将阻塞。
其他 EventWaitHandle
派生的 类 共享相同的通用机制,但允许线程进行时的自动重置与 ManualResetEvent
不同,因此得名。
如果将true
传递给构造函数,则初始状态发出信号(允许线程进行),如果传递false
则不发出信号,因此传递true
是相同的就好像你在构造后立即调用 Set()
而传递 false
相反地就像你调用 Reset()
.
要添加到其他答案,您需要这个的原因(而不是 bool
属性 您只需切换)是:
信号:在 e.WaitOne()
阻塞的线程将被 信号,其中之一将继续。如果您想在没有同步原语的情况下自己执行此操作,则必须实现某种轮询; "blocking" 线程必须定期轮询 bool
(或者说 int
)字段,以检查它是否已更改并允许继续。如果不出意外,这将不必要地消耗 cpu 个周期并且会有延迟(取决于您的轮询间隔)。
原子性:如果有多个线程在等待,你可以保证只有一个不会被阻塞。使用上述轮询解决方案确保相同的行为将需要使用锁定或原子指令(如 Interlocked
class 中的指令)并充分理解可能的编译器和处理器指令 reordering/memory 障碍。
如果您正在寻找一种同步多个线程的简单方法,那么这是 .NET 中最简单(如果不是最简单)的解决方案之一。创建 producer/consumer 队列非常简单:
// 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
会有效地获取已处理。
如果我这样做:
private static System.Threading.AutoResetEvent event_2 = new System.Threading.AutoResetEvent(false);
然后在主线程中我做:
event_2.Set();
它将状态从 false
更改为 true
?
如果是这样,基本上是这样:
AutoResetEventState = !AutoResetEventState
?
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.
如果另一个线程正在使用 event_2.Wait() 等待事件并且您从您的线程调用 .Set() ,等待线程将继续执行。
If so , it basically does :
AutoResetEventState = !AutoResetEventState
?
除此之外,它还将 EventWaitHandle
设置为信号状态,允许一个或多个线程继续进行。
它将状态设置为允许线程在 Wait()
上继续执行的状态。
如果有任何线程已经在等待,那么将允许一个线程继续进行并且状态将立即设置为未设置,因此所有其他线程将继续阻塞。
如果当前没有线程在等待,那么将立即允许第一个等待的线程通过,但后续线程将阻塞。
其他 EventWaitHandle
派生的 类 共享相同的通用机制,但允许线程进行时的自动重置与 ManualResetEvent
不同,因此得名。
如果将true
传递给构造函数,则初始状态发出信号(允许线程进行),如果传递false
则不发出信号,因此传递true
是相同的就好像你在构造后立即调用 Set()
而传递 false
相反地就像你调用 Reset()
.
要添加到其他答案,您需要这个的原因(而不是 bool
属性 您只需切换)是:
信号:在
e.WaitOne()
阻塞的线程将被 信号,其中之一将继续。如果您想在没有同步原语的情况下自己执行此操作,则必须实现某种轮询; "blocking" 线程必须定期轮询bool
(或者说int
)字段,以检查它是否已更改并允许继续。如果不出意外,这将不必要地消耗 cpu 个周期并且会有延迟(取决于您的轮询间隔)。原子性:如果有多个线程在等待,你可以保证只有一个不会被阻塞。使用上述轮询解决方案确保相同的行为将需要使用锁定或原子指令(如
Interlocked
class 中的指令)并充分理解可能的编译器和处理器指令 reordering/memory 障碍。
如果您正在寻找一种同步多个线程的简单方法,那么这是 .NET 中最简单(如果不是最简单)的解决方案之一。创建 producer/consumer 队列非常简单:
// 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
会有效地获取已处理。