Chiarimento su come funziona IAsyncEnumerable con l'API Web ASP.NET


9

Ho riscontrato un comportamento interessante durante l'esplorazione di IAsyncEnumerable in un progetto API Web ASP.NET. Considera i seguenti esempi di codice:

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

Il campione 1 (int array) restituisce {}come risultato JSON.

Il campione 2 restituisce il risultato atteso ["0","1","2","3","4","5","6","7","8","9"]. Tuttavia, l'intero array JSON viene restituito immediatamente dopo 10 secondi di attesa. Non dovrebbero essere restituiti quando i dati diventano disponibili come previsto dall'interfaccia IAsyncEnumerable? O c'è un modo specifico in cui questa API web dovrebbe essere consumata?


4
Non dovrebbero essere restituiti quando i dati diventano disponibili come previsto dall'interfaccia IAsyncEnumerable? ... e lo fa ... ma per il serializzatore JSON
Selvin,

1
e Esempio 1 .... sembra un bug per il tipo non di riferimento (se si cambia IAsyncEnumerable<int>in IAsyncEnumerable<object>- dovrebbe funzionare ma poi è coinvolto un pugilato)
Selvin

@Selvin, la prego di elaborare? O puntare a un esempio di codice? Ho provato a consumare questa API con client C #, il risultato è lo stesso, devo aspettare 10 secondi ...
Ravi M Patel

devi aspettare 10 secondi è ovviosu ... la serializzazione è sul lato server e non è asincrona ... approfondita su cosa?
Selvin,

Risposte:


3

Una chiamata API Web non restituirà json parziale ogni secondo. È il serializzatore json che deve attendere 10x1 secondi (o il codice che chiama il serializzatore json, che fa parte di ASP .NET). Una volta che il codice quadro e il serializzatore ottengono tutti i dati, verranno serializzati serviti - come una singola risposta - al client.

Nei tipi di restituzione dell'azione del controller nell'API Web ASP.NET Core possiamo leggere:

In ASP.NET Core 3.0 e versioni successive, restituendo IAsyncEnumerable da un'azione:

  • Non risulta più in iterazione sincrona.
  • Diventa efficiente come restituire IEnumerable.

ASP.NET Core 3.0 e versioni successive memorizzano nel buffer il risultato della seguente azione prima di fornirlo al serializzatore:

public IEnumerable<Product> GetOnSaleProducts() =>
  _context.Products.Where(p => p.IsOnSale);
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.