Consider the following pattern:
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();
}
The purpose of this pattern is to allow external consumers to wait for a certain event (e.g. - a message arriving). WaitForNextEvent
is not called from within the class.
To give an example that should be familiar, consider System.Diagnostics.Process
. It exposes an Exited
event, but it also exposes a WaitForExit
method, which allows the caller to wait synchronously until the process exits. this is what I am trying to achieve here.
The reason I need signal.Reset()
is that if a thread calls WaitForNextEvent
after signal.Set()
has already been called (or in other words, if .Set
was called when no threads were waiting), it returns immediately, as the event has already been previously signaled.
The question
- Is it guaranteed that a thread calling
WaitForNextEvent()
will be signaled beforesignal.Reset()
is called? If not, what are other solutions for implementing aWaitFor
method?
AutoResetEvent
automatically resets after one thread has successfully waited for it viaWaitOne()
so you should not need to callsignal.Reset()
. – Sectary.Reset()
for anAutoResetEvent
... – SectaryBarrier
lets a specific number of threads all rendezvous and then move forward into a new phase together. – FilariasisWaitOne
afterSet
has been called will block until the nextSet
is called. Could you give an example of how that would work with a semaphore? – StrohTaskCompletionSource
- swapping an old one with a new one before setting the result on the old one. But then realised that if multiple threads were waiting on one, then they would all be released, whereas with theAutoResetEvent
, only one thread can be released. – FilariasisTo give an example that should be familiar, consider System.Diagnostics.Process
Here the event can happen only once. The Process has Exited or it hasn't. After it has exited it can't "restart" and "reexit". The example you gave was a tight cycle with a lock/unlock after each cycle. – OutofdateWaitForExit
, all the threads waiting will be started after the exit :-) – OutofdateAutoResetEvent
would only release one thread. – FilariasisProcess
example is completely different because it is only signalled once. NeitherManualResetEvent
norAutoResetEvent
will work in this situation - they can't be "pulsed" reliably. Matthew's answer usesMonitor
which correctly avoids this problem. – Gasoline