Skip to content

Add support for IAsyncEnumerable<T> #903

Closed
@thomaslevesque

Description

@thomaslevesque

Is your feature request related to a problem? Please describe.

The API for enumerating query results isn't great, because it forces the user to be aware of the fact that the results are fetched page by page:

var iterator = ...
while (iterator.HasMoreResults)
{
    var page = await iterator.ReadNextAsync();
    foreach (var item in page)
    {
        ...
    }
}

Describe the solution you'd like

The FeedIterator<T> API is useful, because it gives you more information (e.g. request charge), but in most cases the user just wants the results, so it would be nice to have a higher level abstraction. The IAsyncEnumerable<T> interface seems perfect for this.

There could be an AsAsyncEnumerable extension method like this:

public static async IAsyncEnumerable<T> AsAsyncEnumerable<T>(
    this FeedIterator<T> iterator,
    [EnumeratorCancellation] CancellationToken cancellationToken = default)
{
    while (iterator.HasMoreResults)
    {
        var page = await iterator.ReadNextAsync(cancellationToken);
        foreach (var item in page)
        {
            cancellationToken.ThrowIfCancellationRequested();
            yield return item;
        }
    }
}

The consuming code would be simplified to this:

var iterator = ...
await foreach (var item in iterator.AsAsyncEnumerable())
{
    ...
}

Describe alternatives you've considered
N/A

Additional context

The await foreach feature was introduced in C# 8, so this would only be useful to people already using C# 8.
However, the Microsoft.Bcl.AsyncInterfaces package is compatible with netstandard2.0 and net461, so it wouldn't require running .NET Core 3.

Metadata

Metadata

Assignees

No one assigned

    Labels

    VNextNext Major version of SDK

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions