У меня есть следующая конечная точка API:
[HttpGet("test")]
public async IAsyncEnumerable<int> GetStrings()
{
Random rnd = new();
foreach (var i in Enumerable.Range(0, 10))
{
await Task.Delay(500);
yield return rnd.Next(100) ;
}
}
Я ожидаю получения потока чисел каждые 500 мс, но этого не происходит, вместо этого он возвращается клиенту через 5 секунд со всей полезной нагрузкой.
Итак, как заставить этот код передавать эти числа в поток? Я использую .NET 8.0.
Буферизация IAsyncEnumerable отсутствует. Сам протокол HTTP не имеет потоковых ответов, для этого и нужны gRPC или WebSockets. Кажется, вы пытаетесь заставить ASP.NET Core возвращать один документ JSON на каждую новую строку в качестве «потокового» ответа. Однако сам ASP.NET Core отправляет ответы порциями, поскольку запись отдельных байтов в сетевой поток будет слишком медленной. Код пытается записать всего 4 байта за раз, всего получается 400. Вероятно, данных слишком мало для немедленной отправки.
Вы используете System.Text.Json или Newtonsoft.Json?
@nsevens да, раньше это работало, как показано в этом ответе
@EnricoMassone я использую System.Text.Json
@PanagiotisKanavos Раньше я тестировал аналогичный код, он отправлял частичный JSON, как показано в этом ответе .... на самом деле мой реальный код создает кучу объектов, создание каждого объекта займет несколько секунд, я просто хочу вернуться данные в том виде, в каком они были созданы, и не ждите, пока все данные будут завершены
Также, вероятно, это связано: stackoverflow.com/questions/78539613/…
@PanagiotisKanavos, просто вопрос с моей стороны. Насколько я понимаю, HTTP может выполнять фрагментированное кодирование передачи, чтобы отправлять данные клиенту, как только данные станут доступны, вместо ожидания генерации всего содержимого ответа. Верно ли мое понимание? Я говорю только на уровне протокола, забудьте на мгновение о поведении ядра ASP.NET.
Итак, как заставить этот код передавать эти числа в поток? Я использую .NET 8.0.
Это связано с тем, как вы отправляете запрос. Согласно статье было написано When using System.Text.Json formatter, MVC relies on the support that System.Text.Json added to stream the result.
.
Если ваше приложение использует правильный пакет System.Text.Json
и убедитесь, что заголовок ответа — application/json
. Тогда вы будете получать поток чисел каждые 500 мс.
Вы можете проверить это, используя вкладку сети разработки F12.
Причина, по которой вы обнаружили, что он просто показывает все цифры, связана с функцией вашего браузера, но на вкладке сети это набор цифр.
Результат:
возможно, это связано: stackoverflow.com/questions/58876817/…