예제 #1
0
        /// <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);
        }
예제 #2
0
        /// <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);
        }