Example #1
0
        /// <summary>
        /// Attempts to enqueue an item. This method may block the calling thread.
        /// </summary>
        /// <param name="item">The item to enqueue.</param>
        /// <param name="cancellationToken">A cancellation token that can be used to abort the enqueue operation.</param>
        internal AsyncProducerConsumerQueue <T> DoTryEnqueue(T item, CancellationToken cancellationToken)
        {
            try
            {
                using (var combinedToken = CancellationTokenHelpers.Normalize(_completed.Token, cancellationToken))
                    using (_mutex.Lock())
                    {
                        // Wait for the queue to be not full.
                        while (Full)
                        {
                            _notFull.Wait(combinedToken.Token);
                        }

                        // Explicitly check whether the queue has been marked complete to prevent a race condition where notFull is signalled at the same time the queue is marked complete.
                        if (_completed.IsCancellationRequested)
                        {
                            return(null);
                        }

                        _queue.Enqueue(item);
                        _completedOrNotEmpty.Notify();
                        return(this);
                    }
            }
            catch (OperationCanceledException)
            {
                return(null);
            }
        }
Example #2
0
 /// <summary>
 /// Attempts to dequeue an item. This method may block the calling thread.
 /// </summary>
 /// <param name="cancellationToken">A cancellation token that can be used to abort the dequeue operation.</param>
 internal DequeueResult DoTryDequeue(CancellationToken cancellationToken)
 {
     try
     {
         using (_mutex.Lock())
         {
             while (!_completed.IsCancellationRequested && Empty)
             {
                 _completedOrNotEmpty.Wait(cancellationToken);
             }
             if (_completed.IsCancellationRequested && Empty)
             {
                 return(FalseResult);
             }
             var item = _queue.Dequeue();
             _notFull.Notify();
             return(new DequeueResult(this, item));
         }
     }
     catch (OperationCanceledException)
     {
         return(FalseResult);
     }
 }
Example #3
0
 /// <summary>
 /// Asynchronously waits for a pulse signal on this monitor. This method may block the calling thread. The monitor MUST already be entered when calling this method, and it will still be entered when this method returns, even if the method is cancelled. This method internally will leave the monitor while waiting for a notification.
 /// </summary>
 /// <param name="cancellationToken">The cancellation signal used to cancel this wait.</param>
 public void Wait(CancellationToken cancellationToken)
 {
     _conditionVariable.Wait(cancellationToken);
 }