web-dev-qa-db-ja.com

IAsyncEnumerableがASP.NET Web APIでどのように機能するかについての説明

ASP.NET Web APIプロジェクトでIAsyncEnumerableを探索しているときに、興味深い動作が発生しました。次のコードサンプルを検討してください。

    // 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インターフェイスから期待どおりにデータが利用可能になったときに返されるべきではありませんか?または、このWeb APIを使用する必要がある特定の方法はありますか?

9
Ravi M Patel

Web API呼び出しは、毎秒部分的なJSONを返しません。 10x1秒待機する必要があるのはjsonシリアライザ(またはASP .NETの一部であるjsonシリアライザを呼び出すコード)です。フレームワークコードとシリアライザがすべてのデータを取得すると、シリアル化されて-単一の応答として-クライアントに提供されます。

ASP.NET Core Web APIのコントローラーアクションの戻り値の型 で読み取ることができます:

ASP.NET Core 3.0以降では、アクションからIAsyncEnumerableを返します。

  • 同期反復が発生しなくなりました。
  • IEnumerableを返すのと同じくらい効率的になります。

ASP.NET Core 3.0以降は、シリアライザに提供する前に、次のアクションの結果をバッファします。

public IEnumerable<Product> GetOnSaleProducts() =>
  _context.Products.Where(p => p.IsOnSale);
3
tymtam