In the .NET documentation for Controller Action Return Types (doc link), it shows this example on how to return a async response stream:
[HttpGet("asyncsale")]
public async IAsyncEnumerable<Product> GetOnSaleProductsAsync()
{
var products = _productContext.Products.OrderBy(p => p.Name).AsAsyncEnumerable();
await foreach (var product in products)
{
if (product.IsOnSale)
{
yield return product;
}
}
}
In the example above, _productContext.Products.OrderBy(p => p.Name).AsAsyncEnumerable()
converts the returned IQueryable<Product>
into an IAsyncEnumerable
. But the below example also works and streams the response asycnhronously.
[HttpGet("asyncsale")]
public async IAsyncEnumerable<Product> GetOnSaleProductsAsync()
{
var products = _productContext.Products.OrderBy(p => p.Name);
foreach (var product in products)
{
if (product.IsOnSale)
{
yield return product;
}
}
await Task.CompletedTask;
}
What's the reason for converting to IAsyncEnumerable
first and doing await
on the foreach
? Is it simply for easier syntax or are there benefits of doing so?
Is there a benefit to converting any IEnumerable
into IAsyncEnumerable
, or only if the underlying IEnumerable
is also streamable, for example through yield
? If I have a list fully loaded into memory already, is it pointless to convert it into an IAsyncEnumerable
?