public async Task <IEnumerator <Tuple> > GetEnumeratorAsync(EnumerationContext context, CancellationToken token) { const string enumerationMarker = "Enumerated"; var enumerated = context.GetValue <bool>(this, enumerationMarker); bool onEnumerationExecuted = false; if (!enumerated) { OnBeforeEnumerate(context); } try { context.SetValue(this, enumerationMarker, true); var enumerator = (await OnEnumerateAsync(context, token).ConfigureAwait(false)) .ToEnumerator( () => { if (!enumerated) { OnAfterEnumerate(context); } }); onEnumerationExecuted = true; return(enumerator); } finally { if (!enumerated && !onEnumerationExecuted) { OnAfterEnumerate(context); } } }
private async ValueTask Prepare(bool executeAsync) { enumerationScope = context.BeginEnumeration(); enumerated = context.GetValue <bool>(provider, enumerationMarker); if (!enumerated) { provider.OnBeforeEnumerate(context); context.SetValue(provider, enumerationMarker, true); } try { dataReader = executeAsync ? await provider.OnEnumerateAsync(context, token).ConfigureAwait(false) : provider.OnEnumerate(context); if (isGreedy && !dataReader.IsInMemory) { var tuples = new List <Tuple>(); if (executeAsync) { await using (dataReader.ConfigureAwait(false)) { while (await dataReader.MoveNextAsync().ConfigureAwait(false)) { tuples.Add(dataReader.Current); } } } else { using (dataReader) { while (dataReader.MoveNext()) { tuples.Add(dataReader.Current); } } } dataReader = new DataReader(tuples); } } catch { FinishEnumeration(true); throw; } state = State.Prepared; }
protected T GetValue <T>(EnumerationContext context, string name) where T : class { context.EnsureIsActive(); return(context.GetValue <T>(this, name)); }
/// <summary> /// Gets value of type <typeparamref name="T"/> previously cached in /// <see cref="EnumerationContext"/> by its <paramref name="name"/>. /// </summary> /// <param name="context"><see cref="EnumerationContext"/> instance where value cache resides.</param> /// <param name="name">The name of the required cached value.</param> /// <typeparam name="T">The type of the value in cache.</typeparam> /// <returns> Cached value with the specified key; /// or <see langword="null"/>, if no cached value is found, or it has already expired. /// </returns> protected T GetValue <T>(EnumerationContext context, string name) where T : class => context.GetValue <T>(this, name);