Асинхронные Потоки в EF Core и ASP.NET Core 6
Давней проблемой в ASP.NET была невозможность обрабатывать возврат больших файлов JSON без использования большого количества памяти. По умолчанию фреймворк выполняет буферизацию всего вывода сразу, конвертирует его весь в JSON, а затем начинает передавать результаты клиенту. Это может привести к нехватке памяти, если объём данных достаточно велик.
Однако потоковая передача результатов не была проблемой для ASP.NET. При работе с более простыми форматами, такими как CSV, разработчик всегда имел возможность писать прямо в поток результатов.
Начиная с ASP.NET Core 5, класс Utf8JsonWriter может использоваться для достижения того же эффекта. Возникнет несколько сложностей, таких как необходимость явного отключения буферизации, но код сможет работать, если вы, например, последуете совету Александра Васильева.
ASP.NET Core 6 упрощает нашу жизнь, напрямую поддерживая
IAsyncEnumerable. Если IAsyncEnumerable возвращается функцией, платформа интерпретирует его как запрос на асинхронную потоковую передачу данных клиенту без буферизации.Один из способов получить
IAsyncEnumerable - использовать Entity Framework Core. Фактически, эта функция присутствовала, начиная с EF Core 3, но до сих пор её полезность на веб-серверах была ограничена. ASP.NET Core не поддерживал результаты типа IAsyncEnumerable до версии 5, но даже в этом случае результаты буферизовались.В объявлении №463 разработчики были проинформированы о том, что новое поведение
IAsyncEnumerable следует рассматривать как критическое изменение.В большинстве случаев приложение не отслеживает отсутствие буферизации. Однако некоторые сценарии могли непреднамеренно полагаться на семантику буферизации для правильной сериализации. Например, возврат
IAsyncEnumerable<>, который поддерживается запросом EF для типа с отложенной загрузкой свойств, может привести к параллельному выполнению запроса, который может не поддерживаться поставщиком.Чтобы вернуться к предыдущему поведению, разработчикам необходимо явно вызвать
ToListAsync():// До ASP.NET Core 6Кроме того, для решения проблемы можно отключить отложенную загрузку.
public IActionResult Get()
{
return Ok(dbContext.Blogs);
}
// Начиная с ASP.NET Core 6
public async Task<IActionResult> Get()
{
return Ok(await dbContext.Blogs.ToListAsync());
}
Источник: https://www.infoq.com/news/2021/06/ASP-Net-Core-6-IAsyncEnumerable/