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.