Esempio n. 1
0
        /// <summary>
        /// Initializes a new instance of the <see cref="AsyncSemaphore"/> class.
        /// </summary>
        /// <param name="initialCount">The initial number of requests for the semaphore that can be granted concurrently.</param>
        public AsyncSemaphore(int initialCount)
        {
            this.semaphore           = new SemaphoreSlim(initialCount);
            this.uncontestedReleaser = Task.FromResult(new Releaser(this));

            this.canceledReleaser = ThreadingTools.TaskFromCanceled <Releaser>(new CancellationToken(canceled: true));
        }
        /// <summary>
        /// Returns an awaitable that may be used to asynchronously acquire the next signal.
        /// </summary>
        /// <param name="cancellationToken">A token whose cancellation removes the caller from the queue of those waiting for the event.</param>
        /// <returns>An awaitable.</returns>
        public Task WaitAsync(CancellationToken cancellationToken)
        {
            if (cancellationToken.IsCancellationRequested)
            {
                return(ThreadingTools.TaskFromCanceled(cancellationToken));
            }

            lock (this.signalAwaiters)
            {
                if (this.signaled)
                {
                    this.signaled = false;
                    return(TplExtensions.CompletedTask);
                }
                else
                {
                    var waiter = new WaiterCompletionSource(this, cancellationToken, this.allowInliningAwaiters);
                    if (cancellationToken.IsCancellationRequested)
                    {
                        waiter.TrySetCanceled(cancellationToken);
                    }
                    else
                    {
                        this.signalAwaiters.Enqueue(waiter);
                    }

                    return(waiter.Task);
                }
            }
        }
Esempio n. 3
0
        /// <summary>
        /// Requests access to the lock.
        /// </summary>
        /// <param name="cancellationToken">A token whose cancellation signals lost interest in the lock.</param>
        /// <returns>A task whose result is a releaser that should be disposed to release the lock.</returns>
        public Task <Releaser> EnterAsync(CancellationToken cancellationToken = default(CancellationToken))
        {
            if (cancellationToken.IsCancellationRequested)
            {
                return(ThreadingTools.TaskFromCanceled <Releaser>(cancellationToken));
            }

            return(this.LockWaitingHelper(this.semaphore.WaitAsync(cancellationToken)));
        }
 public Task SignalAndWaitAsync()
 {
     try
     {
         this.Signal();
         return(this.WaitAsync());
     }
     catch (Exception ex)
     {
         return(ThreadingTools.TaskFromException(ex));
     }
 }
Esempio n. 5
0
        public Task <T> DequeueAsync(CancellationToken cancellationToken = default(CancellationToken))
        {
            if (cancellationToken.IsCancellationRequested)
            {
                return(ThreadingTools.TaskFromCanceled <T>(cancellationToken));
            }

            T result;

            lock (this.SyncRoot)
            {
                if (this.IsCompleted)
                {
                    return(TplExtensions.CanceledTaskOfT <T>());
                }

                if (this.queueElements?.Count > 0)
                {
                    result = this.queueElements.Dequeue();
                }
                else
                {
                    if (this.dequeuingWaiters == null)
                    {
                        this.dequeuingWaiters = new Queue <TaskCompletionSource <T> >(capacity: 2);
                    }
                    else
                    {
                        this.FreeCanceledDequeuers();
                    }

                    var waiterTcs = new TaskCompletionSourceWithoutInlining <T>(allowInliningContinuations: false);
                    waiterTcs.AttachCancellation(cancellationToken, this);
                    this.dequeuingWaiters.Enqueue(waiterTcs);
                    return(waiterTcs.Task);
                }
            }

            this.CompleteIfNecessary();
            return(Task.FromResult(result));
        }
 internal void TrySetCanceled(CancellationToken cancellationToken)
 {
     if (!this.Task.IsCompleted)
     {
         if (this.CanCompleteInline)
         {
             ThreadingTools.TrySetCanceled(this, cancellationToken);
         }
         else
         {
             Tuple <TaskCompletionSourceWithoutInlining <T>, CancellationToken> tuple =
                 Tuple.Create(this, cancellationToken);
             ThreadPool.QueueUserWorkItem(
                 state =>
             {
                 var s = (Tuple <TaskCompletionSourceWithoutInlining <T>, CancellationToken>)state;
                 ThreadingTools.TrySetCanceled(s.Item1, s.Item2);
             },
                 tuple);
         }
     }
 }