protected override async Task <bool> OnNextAsync(CancellationToken cancellationToken) { // if we are in a batch, iterate over it // if not, wait for the next batch while (!cancellationToken.IsCancellationRequested) { if (m_batch == null) { if (!await m_iterator.MoveNextAsync(cancellationToken).ConfigureAwait(false)) { // inner completed return(Completed()); } if (cancellationToken.IsCancellationRequested) { break; } IEnumerable <TResult> sequence; if (!m_selector.Async) { sequence = m_selector.Invoke(m_iterator.Current); } else { sequence = await m_selector.InvokeAsync(m_iterator.Current, cancellationToken).ConfigureAwait(false); } if (sequence == null) { throw new InvalidOperationException("The inner sequence returned a null collection"); } m_batch = sequence.GetEnumerator(); Contract.Assert(m_batch != null); } if (!m_batch.MoveNext()) { // the current batch is exhausted, move to the next m_batch.Dispose(); m_batch = null; continue; } return(Publish(m_batch.Current)); } return(Canceled(cancellationToken)); }
protected override async Task <bool> OnNextAsync(CancellationToken cancellationToken) { if (m_remaining != null && m_remaining.Value <= 0) { // reached limit! return(Completed()); } while (!cancellationToken.IsCancellationRequested) { if (!await m_iterator.MoveNext(cancellationToken).ConfigureAwait(false)) { // completed return(Completed()); } if (cancellationToken.IsCancellationRequested) { break; } #region Filtering... TSource current = m_iterator.Current; if (m_filter != null) { if (!m_filter.Async) { if (!m_filter.Invoke(current)) { continue; } } else { if (!await m_filter.InvokeAsync(current, cancellationToken).ConfigureAwait(false)) { continue; } } } #endregion #region Skipping... if (m_skipped != null) { if (m_skipped.Value > 0) { // skip this result m_skipped = m_skipped.Value - 1; continue; } // we can now start outputing results... m_skipped = null; } #endregion #region Transforming... TResult result; if (!m_transform.Async) { result = m_transform.Invoke(current); } else { result = await m_transform.InvokeAsync(current, cancellationToken).ConfigureAwait(false); } #endregion #region Publishing... if (m_remaining != null) { // decrement remaining quota m_remaining = m_remaining.Value - 1; } return(Publish(result)); #endregion } return(Canceled(cancellationToken)); }