Пояснення того, як IAsyncEnumerable працює з веб-API ASP.NET


9

Я зіткнувся з цікавою поведінкою під час дослідження IAsyncEnumerable у проекті веб-API ASP.NET. Розглянемо наступні зразки коду:

    // 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();
        }
    }

Зразок 1 (масив int) повертається {}як результат JSON.

Зразок 2 повертає очікуваний результат ["0","1","2","3","4","5","6","7","8","9"]. Однак весь масив JSON повертається відразу після 10 секунд очікування. Чи не слід його повернути, оскільки дані стають доступними, як очікувалося від інтерфейсу IAsyncEnumerable? Або існує якийсь конкретний спосіб використання цієї веб-програми?


4
Чи не слід його повернути, оскільки дані стають доступними, як очікувалося від інтерфейсу IAsyncEnumerable? ... і це ... але для серіалізатора json
Селвіна

1
і зразок 1 .... здається помилкою для IAsyncEnumerable<int>IAsyncEnumerable<object>
Селвін

@ Селвін, ви б хотіли детальніше розробити? Або вказати на зразок коду? Я спробував споживати цей API з клієнтом C #, результат такий же, доведеться почекати 10 секунд ...
Ravi M Patel

доведеться почекати 10 секунд, це obviosu ... серіалізація знаходиться на стороні сервера, і це не async ... докладніше про що?
Селвін

Відповіді:


3

Веб-api-дзвінок не повертатиме часткового json щосекунди. Це серіалізатор json, який повинен чекати 10x1секунд (або код, який викликає серійний комбайн json, який є частиною ASP .NET). Як тільки рамковий код і серіалізатор отримають усі дані, він буде серіалізовано подаватися - як єдиний відповідь - клієнту.

У типах повернення дій Controller у веб-API ASP.NET Core ми можемо читати:

В ASP.NET Core 3.0 і пізніших версіях повернення IAsyncEnumerable з дії:

  • Більше не призводить до синхронної ітерації.
  • Стає таким же ефективним, як повернення IEnumerable.

ASP.NET Core 3.0 та пізніші версії буферизують результат наступних дій перед наданням його серіалізатору:

public IEnumerable<Product> GetOnSaleProducts() =>
  _context.Products.Where(p => p.IsOnSale);
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.