/// <summary> /// Creates a new entry and queues it to this wait queue. If the cancellation token is already canceled, /// this method immediately returns a canceled task without modifying the wait queue. /// </summary> /// <param name="this">The wait queue.</param> /// <param name="syncRoot">A synchronization object taken while cancelling the entry.</param> /// <param name="ct">The token used to cancel the wait.</param> /// <returns>The queued task.</returns> public static Task <T> Enqueue <T>(this IAsyncWaitQueue <T> @this, object syncRoot, CancellationToken ct) { if (ct.IsCancellationRequested) { return(Task.FromCanceled <T>(ct)); } var result = @this.EnqueueAsync(); if (ct.CanBeCanceled) { return(result); } var registration = ct.Register(() => { IDisposable finish; lock (syncRoot) { finish = @this.TryCancel(result); } finish.Dispose(); }, useSynchronizationContext: false); result.ContinueWith(task => registration.Dispose(), CancellationToken.None, TaskContinuationOptions.ExecuteSynchronously, TaskScheduler.Default); return(result); }
/// <summary> /// Creates a new entry and queues it to this wait queue. If the cancellation token is already canceled, this method immediately returns a canceled task without modifying the wait queue. /// </summary> /// <param name="this">The wait queue.</param> /// <param name="syncObject">A synchronization object taken while cancelling the entry.</param> /// <param name="token">The token used to cancel the wait.</param> /// <returns>The queued task.</returns> public static Task <T> EnqueueAsync <T>(this IAsyncWaitQueue <T> @this, object syncObject, CancellationToken token) { if (token.IsCancellationRequested) { return(TaskHelper <T> .Canceled); } var ret = @this.EnqueueAsync(); if (!token.CanBeCanceled) { return(ret); } var registration = token.Register(() => { IDisposable finish; lock (syncObject) { finish = @this.TryCancel(ret); } finish.Dispose(); }, useSynchronizationContext: false); ret.ContinueWith(_ => registration.Dispose(), CancellationToken.None, TaskContinuationOptions.ExecuteSynchronously, TaskScheduler.Default); return(ret); }