我们可以使用Wait
和Pulse
模拟ManualResetEvent
,如下所示:
代码#1
readonly object _locker = new object();
bool _signal;
void WaitOne()
{
lock (_locker)
{
while (!_signal) Monitor.Wait (_locker);
}
}
void Set()
{
lock (_locker)
{ _signal = true;
Monitor.PulseAll (_locker);
}
}
void Reset()
{
lock (_locker) _signal = false;
}
细
现在让我们谈谈将其增强为AutoREsetEvent
:
AutoResetEvent
只是用{:1}替换WaitOne
中的代码:
代码#2
lock (_locker)
{
while (!_signal) Monitor.Wait (_locker);
_signal = false;//<---------------
}
并将PulseAll
替换为Pulse
方法中的Set
:
代码#3
lock (_locker)
{ _signal = true;
Monitor.Pulse (_locker);
}
这是一个问题:
在代码#2处,行_signal = false;
。
为什么有必要? Pulse
只会达到 1 等待句柄,我知道AutoREsetEvent
只允许一个被阻止的项目通过并自动关闭大门。
那么为什么要写_signal = false
呢?
答案 0 :(得分:3)
如果_signal
变量保持true
,那么如果另一个线程在<{em> WaitOne
调用之后调用Set
,它就不会等待。您不必只考虑如何处理现有的等待线程 - 您必须考虑对象的整体状态。