C# IAsyncEnumerable

Date: 2020-12-01

Source: https://docs.microsoft.com/en-us/aspnet/core/web-api/action-return-types?view=aspnetcore-5.0

 ASP.NET Core 3.0 and later, returning IAsyncEnumerable<T> from an action:

  • No longer results in synchronous iteration.
  • Becomes as efficient as returning IEnumerable<T>.

ASP.NET Core 3.0 and later buffers the result of the following action before providing it to the serializer:C#Copy

public IEnumerable<Product> GetOnSaleProducts() =>
    _context.Products.Where(p => p.IsOnSale);

Consider declaring the action signature’s return type as IAsyncEnumerable<T> to guarantee the asynchronous iteration. Ultimately, the iteration mode is based on the underlying concrete type being returned. MVC automatically buffers any concrete type that implements IAsyncEnumerable<T>.

Consider the following action, which returns sale-priced product records as IEnumerable<Product>:C#Copy

[HttpGet("syncsale")]
public IEnumerable<Product> GetOnSaleProducts()
{
    var products = _repository.GetProducts();

    foreach (var product in products)
    {
        if (product.IsOnSale)
        {
            yield return product;
        }
    }
}

The IAsyncEnumerable<Product> equivalent of the preceding action is:C#Copy

[HttpGet("asyncsale")]
public async IAsyncEnumerable<Product> GetOnSaleProductsAsync()
{
    var products = _repository.GetProductsAsync();

    await foreach (var product in products)
    {
        if (product.IsOnSale)
        {
            yield return product;
        }
    }
}

Both of the preceding actions are non-blocking as of ASP.NET Core 3.0.

43210cookie-checkC# IAsyncEnumerable