/// <summary> /// Yields an item asynchronously (similar to 'yield return' statement) /// </summary> /// <param name="item">The item of the collection to yield</param> /// <returns>Returns a Task which tells if when you can continue to yield the next item</returns> #pragma warning disable AsyncMethodMustTakeCancellationToken // Does not take a CancellationToken by design public Task ReturnAsync(T item) #pragma warning restore AsyncMethodMustTakeCancellationToken { TaskCompletionSource.Reset(ref _resumeEnumerationTcs); _currentValueContainer.CurrentValue = item; _moveNextCompleteTcs.TrySetResult(true); return(_resumeEnumerationTcs.Task); }
internal ValueTask <bool> OnMoveNext() { if (!IsComplete) { TaskCompletionSource.Reset(ref _moveNextCompleteTcs); _resumeEnumerationTcs?.TrySetResult(true); } return(new ValueTask <bool>(_moveNextCompleteTcs.Task)); }
internal Task <bool> OnMoveNext(CancellationToken cancellationToken) { if (!_isComplete) { CancellationToken = cancellationToken; TaskCompletionSource.Reset(ref _moveNextCompleteTcs); _resumeEnumerationTcs?.TrySetResult(true); } return(_moveNextCompleteTcs.Task); }
public int Take(int max) { if (max <= 0) { throw new ArgumentOutOfRangeException(); } while (true) { lock (this) { if (CurrentCount > 0) { var taken = Math.Min(CurrentCount, max); CurrentCount -= taken; if (CurrentCount == 0) { Available.Reset(); } return(taken); } } Available.WaitOne(); } }