Come restituiresti correttamente una raccolta di oggetti in modo asincrono?

.net async-await c# entity-framework-core system.reactive

Domanda

Devo definire i metodi nell'interfaccia principale che restituiscono le liste. Il mio progetto fa molto affidamento sull'uso di async / await, quindi ho bisogno di definire i miei riferimenti / interfacce core il più asincrono possibile. Uso anche EF7 per il mio livello di accesso ai dati. Attualmente utilizzo IAsyncEnumerable ovunque.

Attualmente sto decidendo se continuare a utilizzare IAsyncEnumerable o tornare all'utilizzo IAsyncEnumerable Task<IEnumerable<T>> . IAsyncEnumerable sembra promettere a questo punto. EF7 lo sta usando anche. Il problema è che non lo so e non riesco a capire come usarlo. Non c'è quasi nulla sul sito web che dice a nessuno come usare Ix.Net . Esiste un'estensione ToAsyncEnumerable che posso utilizzare sugli oggetti IEnumerable , ma ciò non farebbe nulla in modo asincrono (o lo fa ??). Un altro inconveniente è dato dalla firma sottostante:

IAsyncEnumerable GetPersons();

Poiché questa non è una funzione che restituisce Task, non posso usare async / await all'interno del blocco funzione.

D'altra parte, il mio istinto mi sta dicendo che dovrei continuare ad usare Task<IEnumerable<T>> . Questo naturalmente ha anche i suoi problemi. EF non ha un metodo di estensione che restituisce questo tipo. Ha un metodo di estensione ToArrayAsync e ToListAsync , ma questo ovviamente richiede di richiamare l'attesa all'interno del metodo perché Task<T> non è covariante. Questo potenzialmente è un problema perché questo crea un'operazione in più che potrebbe essere evitato se ho semplicemente restituire il Task oggetto.

Le mie domande sono: Devo continuare a usare IAsyncEnumerable (preferito) o dovrei riportare tutto a Task<IEnumerable<T>> (non preferito)? Sono aperto anche ad altri suggerimenti.

Risposta popolare

Vorrei andare con IAsyncEnumerable . Ti permette di mantenere le tue operazioni sia asincrone che pigre.

Senza di esso è necessario tornare Task<IEnumerble> che significa che stai caricando tutti i risultati in memoria. Questo in molti casi significa interrogare e contenere più memoria del necessario.

Il caso classico sta avendo una query che l'utente chiama Any on. Se è Task<IEnumerable> caricherà prima tutti i risultati in memoria, e se è IAsyncEnumerable caricando un risultato sarà sufficiente.

Altrettanto rilevante è che con Task<IEnumerable> è necessario tenere contemporaneamente l'intero set di risultati in memoria mentre con IAsyncEnumerable è possibile "eseguire lo streaming" dei risultati pochi alla volta.

Inoltre, questa è la direzione in cui si sta dirigendo l'ecosistema. È stato aggiunto per estensione reattiva, da una nuova libreria suggerita da Stephen Toub proprio questa settimana e sarà probabilmente supportata nella prossima versione di C # in modo nativo .




Autorizzato sotto: CC-BY-SA with attribution
Non affiliato con Stack Overflow
È legale questo KB? Sì, impara il perché
Autorizzato sotto: CC-BY-SA with attribution
Non affiliato con Stack Overflow
È legale questo KB? Sì, impara il perché