private bool LazilyCreateEvent(out ManualResetEvent waitHandle)
{
waitHandle = new ManualResetEvent(false);
try
{
if (Interlocked.CompareExchange(ref _event, waitHandle, null) == null)
{
if (InternalPeekCompleted)
{
waitHandle.Set();
}
return true;
}
else
{
waitHandle.Dispose();
waitHandle = (ManualResetEvent)_event;
// There's a chance here that _event became null. But the only way is if another thread completed
// in InternalWaitForCompletion and disposed it. If we're in InternalWaitForCompletion, we now know
// IsCompleted is set, so we can avoid the wait when waitHandle comes back null. AsyncWaitHandle
// will try again in this case.
return false;
}
}
catch
{
// This should be very rare, but doing this will reduce the chance of deadlock.
_event = null;
if (waitHandle != null)
{
waitHandle.Dispose();
}
throw;
}
}