We can use Wait and Pulse to simulate a ManualResetEvent as follows:
code #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;
}
fine
now lets talk about enhancing it to be AutoREsetEvent :
an AutoResetEvent is simply a matter of replacing the code in WaitOne with this:
code #2
lock (_locker)
{
while (!_signal) Monitor.Wait (_locker);
_signal = false;//<---------------
}
and replacing PulseAll with Pulse in the Set method:
code #3
lock (_locker)
{ _signal = true;
Monitor.Pulse (_locker);
}
and here is the question :
at code #2 , the line _signal = false;.
why is it necessary ? Pulse will only reach 1 wait handle and I know that AutoREsetEvent is letting only one blocked item to go through and automatically close the gate.
so why writing _signal = false is necessary ? .
If the
_signalvariable staystrue, then if another thread callsWaitOneafter theSetcall, it wouldn’t wait. You don’t just have to consider how existing waiting threads are handled – you have to consider the overall state of the object.