mirror of https://github.com/ogoun/Zero.git
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
48 lines
1.7 KiB
48 lines
1.7 KiB
using System;
|
|
using System.Threading;
|
|
using System.Threading.Tasks;
|
|
|
|
namespace ZeroLevel.Services.Async
|
|
{
|
|
/// <summary>
|
|
/// Holds the task for a cancellation token, as well as the token registration. The registration is disposed when this instance is disposed.
|
|
/// </summary>
|
|
public sealed class CancellationTokenTaskSource<T>
|
|
: IDisposable
|
|
{
|
|
/// <summary>
|
|
/// The cancellation token registration, if any. This is <c>null</c> if the registration was not necessary.
|
|
/// </summary>
|
|
private readonly IDisposable _registration;
|
|
|
|
/// <summary>
|
|
/// Creates a task for the specified cancellation token, registering with the token if necessary.
|
|
/// </summary>
|
|
/// <param name="cancellationToken">The cancellation token to observe.</param>
|
|
public CancellationTokenTaskSource(CancellationToken cancellationToken)
|
|
{
|
|
if (cancellationToken.IsCancellationRequested)
|
|
{
|
|
Task = System.Threading.Tasks.Task.FromCanceled<T>(cancellationToken);
|
|
return;
|
|
}
|
|
var tcs = new TaskCompletionSource<T>();
|
|
_registration = cancellationToken.Register(() => tcs.TrySetCanceled(cancellationToken), useSynchronizationContext: false);
|
|
Task = tcs.Task;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Gets the task for the source cancellation token.
|
|
/// </summary>
|
|
public Task<T> Task { get; private set; }
|
|
|
|
/// <summary>
|
|
/// Disposes the cancellation token registration, if any. Note that this may cause <see cref="Task"/> to never complete.
|
|
/// </summary>
|
|
public void Dispose()
|
|
{
|
|
_registration?.Dispose();
|
|
}
|
|
}
|
|
}
|