Description
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.