In a .NET 6 project, I have to call a web API which is offset paginated (page/per page) and I would like to make the n calls parallel as far as possible.
This is the method which calls the API one time with the given page number:
private Task<ApiResponse> CallApiAsync(int page,
CancellationToken cancellationToken = default)
{
return GetFromJsonAsync<ApiResponse>($"...&page={page}", cancellationToken)
.ConfigureAwait(false);
}
What I actually need is a forward only streamable iterator of all the API calls from page 1 to page n, so given this requirement, I thought IAsyncEnumerable
was the right API to use so I could fire the API calls in parallel and access each API response as soon as one was ready, without needing all of them to be finished.
So I came up with the following code:
public async IAsyncEnumerable<ApiResponse> CallApiEnumerableAsync(int perPage,
[EnumeratorCancellation] CancellationToken cancellationToken = default)
{
int numProducts = GetNumberOfProducts(perPage);
int numCalls = MathExtensions.CeilDiv(numProducts, perPage);
var pages = Enumerable.Range(1, numCalls);
Parallel.ForEach(pages, async page => {
yield return await CallApiAsync(page, cancellationToken).ConfigureAwait(false);
});
yield break;
}
But I get the following error at yield
: CS1621 - The yield statement cannot be used inside an anonymous method or lambda expression.
Is there a way to achieve the result I would like to get?
Feel free to ask questions if I wasn't clear enough!