using System; using System.Threading; using System.Threading.Tasks; namespace ZeroLevel.Services.Async { /// /// Holds the task for a cancellation token, as well as the token registration. The registration is disposed when this instance is disposed. /// public sealed class CancellationTokenTaskSource : IDisposable { /// /// The cancellation token registration, if any. This is null if the registration was not necessary. /// private readonly IDisposable _registration; /// /// Creates a task for the specified cancellation token, registering with the token if necessary. /// /// The cancellation token to observe. public CancellationTokenTaskSource(CancellationToken cancellationToken) { if (cancellationToken.IsCancellationRequested) { Task = System.Threading.Tasks.Task.FromCanceled(cancellationToken); return; } var tcs = new TaskCompletionSource(); _registration = cancellationToken.Register(() => tcs.TrySetCanceled(cancellationToken), useSynchronizationContext: false); Task = tcs.Task; } /// /// Gets the task for the source cancellation token. /// public Task Task { get; private set; } /// /// Disposes the cancellation token registration, if any. Note that this may cause to never complete. /// public void Dispose() { _registration?.Dispose(); } } }