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);
        }