using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
namespace ZeroLevel.Services.Async
{
///
/// Helper methods for cancellation tokens.
///
public static class CancellationTokenHelpers
{
///
/// Initializes the static members.
///
static CancellationTokenHelpers()
{
Canceled = new CancellationToken(true);
}
///
/// Gets , a cancellation token that is never canceled.
///
public static CancellationToken None { get { return CancellationToken.None; } }
///
/// Gets a cancellation token that is already canceled.
///
public static CancellationToken Canceled { get; private set; }
///
/// Creates a cancellation token that is canceled after the due time.
///
/// The due time after which to cancel the token.
/// A cancellation token that is canceled after the due time.
public static NormalizedCancellationToken Timeout(TimeSpan dueTime)
{
var cts = new CancellationTokenSource();
cts.CancelAfter(dueTime);
return new NormalizedCancellationToken(cts);
}
///
/// Creates a cancellation token that is canceled after the due time.
///
/// The due time after which to cancel the token.
/// A cancellation token that is canceled after the due time.
public static NormalizedCancellationToken Timeout(int dueTime)
{
var cts = new CancellationTokenSource();
cts.CancelAfter(dueTime);
return new NormalizedCancellationToken(cts);
}
///
/// Reduces a set of cancellation tokens by removing any cancellation tokens that cannot be canceled. If any tokens are already canceled, the returned token will be canceled.
///
/// The cancellation tokens to reduce.
public static NormalizedCancellationToken Normalize(params CancellationToken[] cancellationTokens)
{
return Normalize((IEnumerable)cancellationTokens);
}
///
/// Reduces a set of cancellation tokens by removing any cancellation tokens that cannot be canceled. If any tokens are already canceled, the returned token will be canceled.
///
/// The cancellation tokens to reduce.
public static NormalizedCancellationToken Normalize(IEnumerable cancellationTokens)
{
var tokens = cancellationTokens.Where(t => t.CanBeCanceled).ToArray();
if (tokens.Length == 0)
return new NormalizedCancellationToken();
if (tokens.Length == 1)
return new NormalizedCancellationToken(tokens[0]);
var alreadyCanceled = tokens.FirstOrDefault(t => t.IsCancellationRequested);
if (alreadyCanceled.IsCancellationRequested)
return new NormalizedCancellationToken(alreadyCanceled);
return new NormalizedCancellationToken(CancellationTokenSource.CreateLinkedTokenSource(tokens));
}
///
/// Creates a cancellation token that is canceled when the provided completes.
///
/// The task to observe.
/// The options to use for the task continuation.
public static NormalizedCancellationToken FromTask(Task source, TaskContinuationOptions continuationOptions)
{
var cts = new CancellationTokenSource();
source.ContinueWith(_ => cts.Cancel(), CancellationToken.None, continuationOptions, TaskScheduler.Default);
return new NormalizedCancellationToken(cts);
}
///
/// Creates a cancellation token that is canceled when the provided completes.
///
/// The task to observe.
public static NormalizedCancellationToken FromTask(Task source)
{
return FromTask(source, TaskContinuationOptions.None);
}
}
}