ASP.NETで長く続いている問題は、大量のメモリを消費せずに大きなJSONファイルを返す処理ができないことである。フレームワークのデフォルトの動作では、出力全体を一度にバッファリングし、それをまとめてJSONに変換してから、結果をクライアントに提供し始める。データ量が非常に多い場合、メモリ不足につながる可能性がある。
結果をストリーミングできないことは、ASP.NETの根本的な問題ではなかった。CSVなどのシンプルなフォーマットの場合、開発者はいつでも結果ストリームに直接書き込むことができる。
ASP.NET Core 5以降、Utf8JsonWriterクラスを同じように使用できる。コードには、バッファリングを明示的に無効にする必要があるなど、いくらか手間があるが、Alexander Vasilyevの指示に従うと機能する。
ASP.NET Core 6では、IAsyncEnumerableを直接サポートすることにより、これが容易になる。IAsyncEnumerable
が関数によって返される場合、フレームワークはそれを、バッファリングせずに非同期でクライアントにデータをストリーミングする要求として解釈する。
IAsyncEnumerable
を取得する1つの方法は、Entity Framework Coreを使うことである。これは実際にはEF Core 3以降の機能であるが、Webサーバでのそのユーティリティはこれまで制限されていた。ASP.NET Coreはバージョン5までIAsyncEnumerable
の結果をサポートしていなかったが、それでも結果をバッファリングしていた。
ASP.NET Core Announcements #463,で、開発者は、新しいIAsyncEnumerable
を重大な変更と見なす必要があることを通知された。
ほとんどの場合、バッファリングがないことはアプリケーションから見られることはありません。ただし、シナリオによっては、正しくシリアル化するために、誤ってバッファリングセマンティクスに依存している場合があります。たとえば、遅延ロードされたプロパティを持つ型で、バックでEFクエリが動く
IAsyncEnumerable<>
を返すと、同時クエリが実行され、それをプロバイダーがサポートしていない可能性があります。
以前の動作に戻すには、開発者はToListAsync()
を明示的に呼び出す必要がある。または、遅延ロードなどの動作を無効にすることもできる。