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


9

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を使用する必要がある特定の方法はありますか?


4
IAsyncEnumerableインターフェイスから期待どおりにデータが利用可能になったときに返されるべきではありませんか?...そして、それはそうです...しかしjsonシリアライザの
セルビン

1
およびサンプル1 ....非参照型のバグのようです(変更IAsyncEnumerable<int>した場合IAsyncEnumerable<object>-動作するはずですが、ボクシングが関係します)
Selvin

@セルビン、詳しく説明してもらえますか?またはコードサンプルを指しますか?私はこのAPIをC#クライアントで使用しようとしましたが、結果は同じで、10秒待つ必要があります...
Ravi M Patel

それはobviosuだ10秒待つ必要があります...シリアル化はサーバー側であり、非同期ではありません...何について詳しく説明しますか?
セルビン

回答:


3

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

ではASP.NETコアウェブAPIにおけるコントローラのアクションの戻り値の型、我々は読むことができます:

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

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

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

public IEnumerable<Product> GetOnSaleProducts() =>
  _context.Products.Where(p => p.IsOnSale);
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.