#if NET20 || NET30 || NET35 || !NET_4_6 using System.Diagnostics.Contracts; namespace System.Threading.Tasks { public partial class Task { /// A task that's already been completed successfully. private static Task _completedTask; /// Gets a task that's already been completed successfully. /// May not always return the same instance. internal static Task CompletedTask { get { var completedTask = _completedTask; if (completedTask == null) { _completedTask = completedTask = CreateCompletedTask(); } return completedTask; } } /// /// Creates a Task that will complete after a time delay. /// /// The time span to wait before completing the returned Task /// A Task that represents the time delay /// /// The is less than -1 or greater than Int32.MaxValue. /// /// /// After the specified time delay, the Task is completed in RanToCompletion state. /// public static Task Delay(TimeSpan delay) { return Delay(delay, default(CancellationToken)); } /// /// Creates a Task that will complete after a time delay. /// /// The time span to wait before completing the returned Task /// The cancellation token that will be checked prior to completing the returned Task /// A Task that represents the time delay /// /// The is less than -1 or greater than Int32.MaxValue. /// /// /// The provided has already been disposed. /// /// /// If the cancellation token is signaled before the specified time delay, then the Task is completed in /// Canceled state. Otherwise, the Task is completed in RanToCompletion state once the specified time /// delay has expired. /// public static Task Delay(TimeSpan delay, CancellationToken cancellationToken) { var totalMilliseconds = (long)delay.TotalMilliseconds; if (totalMilliseconds < -1 || totalMilliseconds > int.MaxValue) { throw new ArgumentOutOfRangeException("delay", "The value needs to translate in milliseconds to - 1(signifying an infinite timeout), 0 or a positive integer less than or equal to Int32.MaxValue"); } return Delay((int)totalMilliseconds, cancellationToken); } /// /// Creates a Task that will complete after a time delay. /// /// The number of milliseconds to wait before completing the returned Task /// A Task that represents the time delay /// /// The is less than -1. /// /// /// After the specified time delay, the Task is completed in RanToCompletion state. /// public static Task Delay(int millisecondsDelay) { return Delay(millisecondsDelay, default(CancellationToken)); } /// /// Creates a Task that will complete after a time delay. /// /// The number of milliseconds to wait before completing the returned Task /// The cancellation token that will be checked prior to completing the returned Task /// A Task that represents the time delay /// /// The is less than -1. /// /// /// The provided has already been disposed. /// /// /// If the cancellation token is signaled before the specified time delay, then the Task is completed in /// Canceled state. Otherwise, the Task is completed in RanToCompletion state once the specified time /// delay has expired. /// public static Task Delay(int millisecondsDelay, CancellationToken cancellationToken) { // Throw on non-sensical time if (millisecondsDelay < -1) { throw new ArgumentOutOfRangeException("millisecondsDelay", "The value needs to be either -1 (signifying an infinite timeout), 0 or a positive integer."); } Contract.EndContractBlock(); // some short-cuts in case quick completion is in order if (cancellationToken.IsCancellationRequested) { // return a Task created as already-Canceled return FromCancellation(cancellationToken); } if (millisecondsDelay == 0) { // return a Task created as already-RanToCompletion return CompletedTask; } var source = new TaskCompletionSource(); if (millisecondsDelay > 0) { var timeout = new LinqInternal.Threading.Timeout ( () => { try { source.SetResult(true); } catch (InvalidOperationException exception) { // Already cancelled GC.KeepAlive(exception); } }, millisecondsDelay, cancellationToken ); source.Task.SetPromiseCheck(() => timeout.CheckRemaining()); } if (cancellationToken.CanBeCanceled) { cancellationToken.Register ( () => { try { source.SetCanceled(); } catch (InvalidOperationException exception) { // Already timeout GC.KeepAlive(exception); } } ); } return source.Task; } } } #endif