コード例 #1
0
        /// <summary>
        /// Sets the <paramref name="taskCompletionSource"/> to fault with a <see cref="TimeoutException"/> after
        /// the given <paramref name="timeout"/>. Returns the input <paramref name="taskCompletionSource"/>
        /// </summary>
        public static TaskCompletionSource <TResult> TimeoutAfter <TResult>(this TaskCompletionSource <TResult> taskCompletionSource, TimeSpan timeout)
        {
            if (taskCompletionSource == null)
            {
                throw new ArgumentNullException(nameof(taskCompletionSource));
            }
            timeout.AssertIsValidTimeout();

            if (timeout != Timeout.InfiniteTimeSpan)
            {
                var timeoutCanceler = new CancellationTokenSource();
                var timeoutTask     = Task.Delay(timeout, timeoutCanceler.Token);

                // timeout cancels the source
                timeoutTask.SynchronousContinueWith(
                    (task, state) => ((TaskCompletionSource <TResult>)state).TrySetException(new TimeoutException("Timeout of " + timeout + " expired!")),
                    state: taskCompletionSource,
                    continuationOptions: TaskContinuationOptions.OnlyOnRanToCompletion
                    );

                // source cleans up the timeout
                taskCompletionSource.Task.SynchronousContinueWith(
                    (task, state) => ((CancellationTokenSource)state).Cancel(),
                    state: timeoutCanceler
                    );
            }

            return(taskCompletionSource);
        }
コード例 #2
0
        /// <summary>
        /// Asynchronously waits up to <paramref name="timeout"/> for <paramref name="task"/>
        /// to complete. The result of the returned <see cref="Task{TResult}"/> indicates whether
        /// or not the <paramref name="task"/> completed
        /// </summary>
        public static Task <bool> WaitAsync(this Task task, TimeSpan timeout)
        {
            if (task == null)
            {
                throw new ArgumentNullException(nameof(task));
            }
            timeout.AssertIsValidTimeout();

            if (task.IsCompleted)
            {
                return(TrueTask); // hot path
            }

            return(InternalWaitAsync(task, timeout));
        }