/// <summary> /// Way 2: batched enumeration with periodical context activation /// </summary> private IEnumerator <Tuple> GetBatchedEnumerator() { EnumerationScope currentScope = null; var batched = Source.Batch(2).ApplyBeforeAndAfter( () => currentScope = Context.Activate(), () => currentScope.DisposeSafely()); using (var cs = Context.BeginEnumeration()) { foreach (var batch in batched) { foreach (var tuple in batch) { yield return(tuple); } } if (cs != null) { cs.Complete(); } } }
/// <summary> /// Way 2: batched async enumeration. /// </summary> private async Task <IEnumerator <Tuple> > GetBatchedEnumeratorAsync(CancellationToken token) { EnumerationScope currentScope = null; var enumerator = await Source.GetEnumeratorAsync(Context, token).ConfigureAwait(false); var batched = enumerator.ToEnumerable().Batch(2); var cs = Context.BeginEnumeration(); Action <object> afterEnumerationAction = o => { if (o == null) { return; } var completableScope = (ICompletableScope)o; completableScope.Complete(); completableScope.Dispose(); }; return(GetTwoLevelEnumerator(batched, afterEnumerationAction, cs)); }