来自文档(EventWaitHandle.Set)
不能保证每次调用 Set 方法都会从重置模式为 EventResetMode.AutoReset 的 EventWaitHandle 中释放线程。如果两个调用靠得太近,以至于第二个调用发生在一个线程被释放之前,那么只有一个线程被释放。就好像第二次通话没有发生一样。此外,如果在没有线程等待且 EventWaitHandle 已发出信号时调用 Set,则该调用无效。
考虑以下代码
private AutoResetEvent _are = new AutoResetEvent(false);
private void AnyMethod()
{
await _are.Set();
}
情况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;
}
案例二
private void Method1(int timeout)
{
_are.WaitOne(timeout);
}
private void Method2()
{
_are.WaitOne();
}
想象一下,两者Method1
都Method2
被调用,然后AnyMethod
在超时时及时释放一个线程Method1
。
在情况 1 和 2 中是否有关于线程释放的保证,或者Set
方法行为通常适用于任何线程释放,当其中任何一个发生在另一个附近时?