From doc (EventWaitHandle.Set)
There is no guarantee that every call to the Set method will release a thread from an EventWaitHandle whose reset mode is EventResetMode.AutoReset. If two calls are too close together, so that the second call occurs before a thread has been released, only one thread is released. It is as if the second call did not happen. Also, if Set is called when there are no threads waiting and the EventWaitHandle is already signaled, the call has no effect.
Consider following code
private AutoResetEvent _are = new AutoResetEvent(false);
private void AnyMethod()
{
await _are.Set();
}
Case 1
private async Task Method1(long timeout)
{
await _are.WaitOneAsync(timeout);
}
private async Task Method2()
{
await _are.WaitOneAsync();
}
private static Task WaitOneAsync(this WaitHandle waitHandle, long timeout)
{
if (waitHandle == null)
throw new ArgumentNullException("waitHandle");
var tcs = new TaskCompletionSource<bool>();
var rwh = ThreadPool.RegisterWaitForSingleObject(waitHandle,
delegate { tcs.TrySetResult(true); }, null, timeout, true);
var t = tcs.Task;
t.ContinueWith( (antecedent) => rwh.Unregister(null));
return t;
}
Case 2
private void Method1(int timeout)
{
_are.WaitOne(timeout);
}
private void Method2()
{
_are.WaitOne();
}
Imagine that both Method1
and Method2
are called and then AnyMethod
releases one thread right in time when Method1
times out.
Is there guarantee about a thread releasement in the case 1 and 2 or Set
method behavior applies generally to any thread releasement when either occurs close to another?
The documentation quote describes what happens when
Set
is called and there are no threads waiting. The code in the rest of your question is all about callingSet
when threads are waiting, so that paragraph of the docs doesn't apply.Yes; one of the waiting threads will be released. If the event is
Set
before the timeout, it could be either thread; if the event isSet
after the timeout, it will be the thread without the timeout.