Exemple #1
0
        public static WaitAsyncOperation Start(WaitHandle waitHandle, int millisecondsTimeout, CancellationToken cancellationToken)
        {
            var value = new WaitAsyncOperation();

            value.StartImpl(waitHandle, millisecondsTimeout, cancellationToken);
            return(value);
        }
Exemple #2
0
        /// <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));
        }