private Task <bool> WaitToWriteAsync(CancellationToken cancellationToken = default(CancellationToken))
        {
            if (cancellationToken.IsCancellationRequested)
            {
                return(Task.FromCanceled <bool>(cancellationToken));
            }

            lock (SyncObj)
            {
                AssertInvariants();

                // If we're done writing, no writes will ever succeed.
                if (_doneWriting != null)
                {
                    return(ChannelUtilities.FalseTask);
                }

                // If there's space to write, a write is possible.
                // And if the mode involves dropping, we can always write, as even if it's
                // full we'll just drop an element to make room.
                if (_items.Count < _bufferedCapacity || _mode != BoundedChannelFullMode.Wait)
                {
                    return(ChannelUtilities.TrueTask);
                }

                // We're still allowed to write, but there's no space, so ensure a waiter is queued and return it.
                return(ChannelUtilities.GetOrCreateWaiter(ref _waitingWriters, true, cancellationToken));
            }
        }
        private Task <bool> WaitToReadAsync(CancellationToken cancellationToken = default(CancellationToken))
        {
            if (cancellationToken.IsCancellationRequested)
            {
                return(Task.FromCanceled <bool>(cancellationToken));
            }

            lock (SyncObj)
            {
                AssertInvariants();

                // If there are any items available, a read is possible.
                if (!_items.IsEmpty)
                {
                    return(ChannelUtilities.TrueTask);
                }

                // There were no items available, so if we're done writing, a read will never be possible.
                if (_doneWriting != null)
                {
                    return(ChannelUtilities.FalseTask);
                }

                // There were no items available, but there could be in the future, so ensure
                // there's a blocked reader task and return it.
                return(ChannelUtilities.GetOrCreateWaiter(ref _waitingReaders, _runContinuationsAsynchronously, cancellationToken));
            }
        }
        private Task <bool> WaitToWriteAsync(CancellationToken cancellationToken = default(CancellationToken))
        {
            lock (SyncObj)
            {
                // If we're done writing, fail.
                if (_completion.Task.IsCompleted)
                {
                    return(ChannelUtilities.FalseTask);
                }

                // If there's a blocked reader, we can write
                if (!_blockedReaders.IsEmpty)
                {
                    return(ChannelUtilities.TrueTask);
                }

                // Otherwise, queue the writer
                return(ChannelUtilities.GetOrCreateWaiter(ref _waitingWriters, true, cancellationToken));
            }
        }
Esempio n. 4
0
        private Task <bool> WaitToReadAsync(CancellationToken cancellationToken = default(CancellationToken))
        {
            lock (SyncObj)
            {
                // If we're done writing, fail.
                if (_completion.Task.IsCompleted)
                {
                    return(_completion.Task.IsFaulted ?
                           Task.FromException <bool>(_completion.Task.Exception.InnerException) :
                           ChannelUtilities.FalseTask);
                }

                // If there's a blocked writer, we can read.
                if (!_blockedWriters.IsEmpty)
                {
                    return(ChannelUtilities.TrueTask);
                }

                // Otherwise, queue the waiter.
                return(ChannelUtilities.GetOrCreateWaiter(ref _waitingReaders, true, cancellationToken));
            }
        }