public override Task <bool> WaitToReadAsync(CancellationToken cancellationToken)
            {
                // If there are any items, readers can try to get them.
                return(!_parent._items.IsEmpty ?
                       ChannelUtilities.s_trueTask :
                       WaitToReadAsyncCore(cancellationToken));

                Task <bool> WaitToReadAsyncCore(CancellationToken ct)
                {
                    UnboundedChannel <T> parent = _parent;

                    lock (parent.SyncObj)
                    {
                        parent.AssertInvariants();

                        // Try again to read now that we're synchronized with writers.
                        if (!parent._items.IsEmpty)
                        {
                            return(ChannelUtilities.s_trueTask);
                        }

                        // There are no items, so if we're done writing, there's never going to be data available.
                        if (parent._doneWriting != null)
                        {
                            return(parent._doneWriting != ChannelUtilities.s_doneWritingSentinel ?
                                   Task.FromException <bool>(parent._doneWriting) :
                                   ChannelUtilities.s_falseTask);
                        }

                        // Queue the waiter
                        return(ChannelUtilities.GetOrCreateWaiter(ref parent._waitingReaders, parent._runContinuationsAsynchronously, ct));
                    }
                }
            }
            public override Task <bool> WaitToReadAsync(CancellationToken cancellationToken)
            {
                if (cancellationToken.IsCancellationRequested)
                {
                    return(Task.FromCanceled <bool>(cancellationToken));
                }

                BoundedChannel <T> parent = _parent;

                lock (parent.SyncObj)
                {
                    parent.AssertInvariants();

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

                    // There were no items available, so if we're done writing, a read will never be possible.
                    if (parent._doneWriting != null)
                    {
                        return(parent._doneWriting != ChannelUtilities.s_doneWritingSentinel ?
                               Task.FromException <bool>(parent._doneWriting) :
                               ChannelUtilities.s_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 parent._waitingReaders, parent._runContinuationsAsynchronously, cancellationToken));
                }
            }
Example #3
0
            public override Task <bool> WaitToReadAsync(CancellationToken cancellationToken)
            {
                UnbufferedChannel <T> parent = _parent;

                lock (parent.SyncObj)
                {
                    // If we're done writing, fail.
                    if (parent._completion.Task.IsCompleted)
                    {
                        return(parent._completion.Task.IsFaulted ?
                               Task.FromException <bool>(parent._completion.Task.Exception.InnerException) :
                               ChannelUtilities.s_falseTask);
                    }

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

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