private void DoCompletion(int targetState) { if (WaitHandleAsyncOperations.TryChangeState(ref _state, expectedState: State_Waiting, newState: State_Completing)) { _waitRegistration.Unregister(null); _ctRegistration.Dispose(); _state = targetState; InvokeContinuation(); } }
/// <summary> /// Starts waiting on the <see cref="System.Threading.WaitHandle"/> to pulse on a separate thread /// </summary> /// <param name="waitHandle">The <see cref="System.Threading.WaitHandle"/> to wait on</param> /// <param name="timeoutMs">The wait timeout, or -1 to wait indefinitely</param> /// <param name="cancellationToken">The wait cancellation token</param> /// <returns>An instance of the awaiter</returns> internal static WaitHandleAwaiter StartWaiting(WaitHandle waitHandle, int timeoutMs, CancellationToken cancellationToken) { WaitHandleAsyncOperations.ThrowIfMutex(waitHandle); cancellationToken.ThrowIfCancellationRequested(); var awaiter = new WaitHandleAwaiter() { _waitHandle = waitHandle, _timeoutMs = timeoutMs }; awaiter._waitRegistration = ThreadPool.RegisterWaitForSingleObject(waitHandle, WaitCallback, awaiter, timeoutMs, executeOnlyOnce: true); if (cancellationToken.CanBeCanceled) { awaiter._ctRegistration = cancellationToken.Register(awaiter.OnCancelRequested, useSynchronizationContext: false); } return(awaiter); }