System.Text.Js を使用する場合、IAsyncEnumerable 型は MVC によりバッファー処理されない

ASP.NET Core 5 において、MVC ではシーケンスをメモリにバッファリングし、バッファー処理されたコレクションをフォーマットすることにより、出力フォーマットの IAsyncEnumerable<T> 型をサポートするようになりました。 ASP.NET Core 6 では、System.Text.Json を使用したフォーマット時に、MVC によって IAsyncEnumerable<T> インスタンスがバッファー処理されなくなりました。 代わりに、MVC は、System.Text.Json によって、これらの型に対して追加されたサポートに依存しています。

ほとんどの場合、バッファリングが存在しないことをアプリケーションで監視することはできません。 ただし、シナリオによっては、正しくシリアル化するために、誤ってバッファリング セマンティクスに依存している場合があります。 たとえば、遅延読み込みプロパティを持つ型で Entity Framework クエリに基づく IAsyncEnumerable<T> を返すと、クエリが同時に実行される可能性がありますが、これはプロバイダーでサポートされていない場合があります。

この変更は、Newtonsoft.Json または XML ベースのフォーマッタを使用した出力フォーマットには影響しません。

導入されたバージョン

ASP.NET Core 6.0

以前の動作

ObjectResult または JsonResult を使用してフォーマットされる値として MVC アクションから返された IAsyncEnumerable<T> インスタンスは、同期コレクションとしてシリアル化される前にバッファー処理されます。

新しい動作

System.Text.Json を使用したフォーマット時に、MVC によって IAsyncEnumerable<T> インスタンスがバッファー処理されなくなりました。

変更理由

System.Text.Json では、ストリーミング IAsyncEnumerable<T> 型をサポートするようになりました。 これにより、シリアル化時のメモリ占有領域を小さくすることができます。

アプリケーションでバッファリングが必要な場合は、IAsyncEnumerable<T> オブジェクトを手動でバッファリングすることを検討してください。

// Before
public IActionResult Get()
{
    return Ok(dbContext.Blogs);
}

// After
public async Task<IActionResult> Get()
{
    return Ok(await dbContext.Blogs.ToListAsync());
}