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)); } }
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)); } }