考虑以下模式:
private AutoResetEvent signal = new AutoResetEvent(false);
private void Work()
{
while (true)
{
Thread.Sleep(5000);
signal.Set();
//has a waiting thread definitely been signaled by now?
signal.Reset();
}
}
public void WaitForNextEvent()
{
signal.WaitOne();
}
此模式的目的是允许外部消费者等待特定事件(例如 - 消息到达)。 WaitForNextEvent
不是从类中调用的。
举一个大家应该很熟悉的例子,考虑System.Diagnostics.Process
。它公开了一个 Exited
事件,但它也公开了一个 WaitForExit
方法,允许调用者同步等待直到进程退出。这就是我要在这里实现的目标。
我需要 signal.Reset()
的原因是,如果线程调用 WaitForNextEvent
after signal.Set()
已经被调用(或者换句话说,如果在没有线程等待时调用了 .Set
),它会立即返回,因为事件之前已经发出信号。
问题
- 是否保证调用
WaitForNextEvent()
的线程将在signal.Reset()
被调用之前收到信号?如果不是,还有哪些其他解决方案可以实现WaitFor
方法?
最佳答案
不要使用 AutoResetEvent
或 ManualResetEvent
,而是使用:
public sealed class Signaller
{
public void PulseAll()
{
lock (_lock)
{
Monitor.PulseAll(_lock);
}
}
public void Pulse()
{
lock (_lock)
{
Monitor.Pulse(_lock);
}
}
public void Wait()
{
Wait(Timeout.Infinite);
}
public bool Wait(int timeoutMilliseconds)
{
lock (_lock)
{
return Monitor.Wait(_lock, timeoutMilliseconds);
}
}
private readonly object _lock = new object();
}
然后像这样更改您的代码:
private Signaller signal = new Signaller();
private void Work()
{
while (true)
{
Thread.Sleep(5000);
signal.Pulse(); // Or signal.PulseAll() to signal ALL waiting threads.
}
}
public void WaitForNextEvent()
{
signal.Wait();
}
关于c# - AutoResetEvent 设置后立即复位,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18609285/