#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