/// <summary> /// Asynchronously waits <paramref name="millisecondsTimeout"/> milliseconds for the process to exit. /// </summary> /// <param name="millisecondsTimeout">The amount of time in milliseconds to wait for the process to exit. <see cref="Timeout.Infinite"/> means infinite amount of time.</param> /// <param name="cancellationToken"><see cref="CancellationToken"/> to cancel the wait operation.</param> /// <returns>A <see cref="Task"/> representing the asynchronous wait operation. true if the process has exited. Otherwise false.</returns> public Task <bool> WaitForExitAsync(int millisecondsTimeout, CancellationToken cancellationToken = default) { ArgumentValidationUtil.CheckTimeOutRange(millisecondsTimeout); CheckNotDisposed(); if (_hasExitCode) { return(CompletedBoolTask.True); } // Synchronous path: the process has already exited. if (_waitHandle.WaitOne(0)) { DangerousRetrieveExitCode(); return(CompletedBoolTask.True); } // Synchronous path: already canceled. if (cancellationToken.IsCancellationRequested) { return(Task.FromCanceled <bool>(cancellationToken)); } // Start an asynchronous wait operation. var operation = new WaitAsyncOperation(); return(operation.StartAsync(_waitHandle, millisecondsTimeout, cancellationToken)); }
/// <summary> /// Asynchronously waits <paramref name="millisecondsTimeout"/> milliseconds for all the processes in the pipeline to exit. /// </summary> /// <param name="millisecondsTimeout">The amount of time in milliseconds to wait for the processes to exit. <see cref="Timeout.Infinite"/> means infinite amount of time.</param> /// <param name="cancellationToken"><see cref="CancellationToken"/> to cancel the wait operation.</param> /// <returns>A <see cref="Task"/> representing the asynchronous wait operation. true if the processes have exited. Otherwise false.</returns> public Task <bool> WaitForExitAsync(int millisecondsTimeout, CancellationToken cancellationToken = default) { ArgumentValidationUtil.CheckTimeOutRange(millisecondsTimeout); CheckNotDisposed(); if (_hasExitCodes) { return(CompletedBoolTask.True); } Debug.Assert(_waitHandles.Length != 0); // Collect unsignaled handles. int unsignaledHandleCount = 0; Span <bool> signaled = stackalloc bool[_waitHandles.Length]; for (int i = 0; i < _waitHandles.Length; i++) { if (_waitHandles[i].WaitOne(0)) { signaled[i] = true; } else { signaled[i] = false; unsignaledHandleCount++; } } // Synchronous path: all the process have already exited. if (unsignaledHandleCount == 0) { DangerousRetrieveExitCodes(); return(CompletedBoolTask.True); } // Synchronous path: already canceled. if (cancellationToken.IsCancellationRequested) { return(Task.FromCanceled <bool>(cancellationToken)); } // Start asynchronous wait operations. var waitTasks = new Task <bool> [unsignaledHandleCount]; var waitTaskIndex = 0; for (int i = 0; i < _waitHandles.Length; i++) { if (!signaled[i]) { waitTasks[waitTaskIndex++] = new WaitAsyncOperation().StartAsync(_waitHandles[i], millisecondsTimeout, cancellationToken); } } return(Task.WhenAll(waitTasks).ContinueWith(CachedAreAllWaitSuccessfulDelegate, waitTasks, cancellationToken)); }
/// <summary> /// Waits <paramref name="millisecondsTimeout"/> milliseconds for the process to exit. /// </summary> /// <param name="millisecondsTimeout">The amount of time in milliseconds to wait for the process to exit. <see cref="Timeout.Infinite"/> means infinite amount of time.</param> /// <returns>true if the process has exited. Otherwise false.</returns> public bool WaitForExit(int millisecondsTimeout) { ArgumentValidationUtil.CheckTimeOutRange(millisecondsTimeout); CheckNotDisposed(); if (_hasExitCode) { return(true); } if (!_waitHandle.WaitOne(millisecondsTimeout)) { return(false); } DangerousRetrieveExitCode(); return(true); }
/// <summary> /// Waits <paramref name="millisecondsTimeout"/> milliseconds for the process to exit. /// </summary> /// <param name="millisecondsTimeout">The amount of time in milliseconds to wait for the process to exit. <see cref="Timeout.Infinite"/> means infinite amount of time.</param> /// <returns>true if the process has exited. Otherwise false.</returns> public bool WaitForExit(int millisecondsTimeout) { ArgumentValidationUtil.CheckTimeOutRange(millisecondsTimeout); CheckNotDisposed(); var state = _stateHolder.State; if (state.HasExitCode) { return(true); } if (!state.ExitedWaitHandle.WaitOne(millisecondsTimeout)) { return(false); } state.DangerousRetrieveExitCode(); return(true); }
/// <summary> /// Waits <paramref name="millisecondsTimeout"/> milliseconds for all the processes in the pipeline to exit. /// </summary> /// <param name="millisecondsTimeout">The amount of time in milliseconds to wait for the processes to exit. <see cref="Timeout.Infinite"/> means infinite amount of time.</param> /// <returns>true if the processes have exited. Otherwise false.</returns> public bool WaitForExit(int millisecondsTimeout) { ArgumentValidationUtil.CheckTimeOutRange(millisecondsTimeout); CheckNotDisposed(); if (_hasExitCodes) { return(true); } Debug.Assert(_waitHandles.Length != 0); if (!WaitHandle.WaitAll(_waitHandles, millisecondsTimeout)) { return(false); } DangerousRetrieveExitCodes(); return(true); }