Klarifikasi tentang cara kerja IAsyncEnumerable dengan ASP.NET Web API

9

Saya menemukan perilaku yang menarik saat menjelajahi IAsyncEnumerable dalam proyek ASP.NET Web API. Pertimbangkan contoh kode berikut:

    // 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();
        }
    }

Sampel 1 (array int) kembali {}sebagai hasil JSON.

Sampel 2 mengembalikan hasil yang diharapkan ["0","1","2","3","4","5","6","7","8","9"]. Namun, seluruh array JSON dikembalikan sekaligus setelah 10 detik menunggu. Tidakkah seharusnya dikembalikan saat data tersedia seperti yang diharapkan dari antarmuka IAsyncEnumerable? Atau adakah cara khusus api web ini harus dikonsumsi?

Ravi M Patel
sumber
4
Tidakkah seharusnya dikembalikan saat data tersedia seperti yang diharapkan dari antarmuka IAsyncEnumerable? ... dan memang ... tetapi untuk serialson json
Selvin
1
dan Sampel 1 .... tampaknya seperti bug untuk jenis referensi non (jika Anda mengubah IAsyncEnumerable<int>ke IAsyncEnumerable<object>- harus bekerja tapi kemudian ada tinju yang terlibat)
Selvin
@ Selvin, tolong jelaskan? Atau arahkan ke contoh kode? Saya mencoba mengkonsumsi API ini dengan klien C #, hasilnya sama, harus menunggu 10 detik ...
Ravi M Patel
harus menunggu 10 detik itu obviosu ... serialisasi ada di sisi server dan tidak async ... rumit tentang apa?
Selvin
1
bug ada di sini ... jelas itu sebabnya
Selvin

Jawaban:

3

Panggilan api web tidak akan mengembalikan sebagian json setiap detik. Ini adalah serialiser json yang harus menunggu 10x1second (atau kode yang memanggil serialiser json, yang merupakan bagian dari ASP .NET). Setelah kode kerangka kerja dan serialiser mendapatkan semua data, itu akan disajikan secara serial - sebagai satu tanggapan - kepada klien.

Dalam jenis tindakan pengembalian Controller di API web ASP.NET Core kita dapat membaca:

Di ASP.NET Core 3.0 dan yang lebih baru, mengembalikan IAsyncEnumerable dari tindakan:

  • Tidak lagi menghasilkan iterasi sinkron.
  • Menjadi seefisien pengembalian IEnumerable.

ASP.NET Core 3.0 dan yang lebih baru mendukung hasil dari tindakan berikut sebelum memberikannya kepada serializer:

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