问题
I encountered an interesting behavior while exploring IAsyncEnumerable in an ASP.NET Web API project. Consider the following code samples:
// Code Sample 1
[HttpGet]
public async IAsyncEnumerable<int> GetAsync()
{
for (int i = 0; i < 10; i++)
{
await Task.Delay(1000);
yield return i;
}
}
// Code Sample 2
[HttpGet]
public async IAsyncEnumerable<string> GetAsync()
{
for (int i = 0; i < 10; i++)
{
await Task.Delay(1000);
yield return i.ToString();
}
}
Sample 1 (int array) returns {}
as JSON result.
Sample 2 returns expected result ["0","1","2","3","4","5","6","7","8","9"]
. However, entire JSON array is returned at once after 10 seconds of wait. Shouldn't it be returned as data becomes available as expected from IAsyncEnumerable interface? Or is there any specific way this web api should be consumed?
回答1:
A web api call will not return partial json every second. It's the json serialiser who has to wait 10x1second (or the code that calls the json serialiser, which is part of ASP .NET). Once the framework code and the serialiser get all data, it will be serialised and served to the client as a single response.
In Controller action return types in ASP.NET Core web API we can read:
In ASP.NET Core 3.0 and later, returning IAsyncEnumerable from an action:
- No longer results in synchronous iteration.
- Becomes as efficient as returning IEnumerable.
ASP.NET Core 3.0 and later buffers the result of the following action before providing it to the serializer:
public IEnumerable<Product> GetOnSaleProducts() =>
_context.Products.Where(p => p.IsOnSale);
来源:https://stackoverflow.com/questions/58876817/clarification-on-how-iasyncenumerable-works-with-asp-net-web-api