Comment renverriez-vous correctement une collection d'objets de manière asynchrone?

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

Question

Je dois définir des méthodes dans mon interface principale qui renvoient des listes. Mon projet repose fortement sur l'utilisation de async / wait. Je dois donc définir mes références / interfaces principales de manière aussi asynchrone que possible. J'utilise également EF7 pour ma couche d'accès aux données. J'utilise actuellement IAsyncEnumerable partout.

Je suis actuellement en train de décider de continuer à utiliser IAsyncEnumerable ou de revenir à la Task<IEnumerable<T>> . IAsyncEnumerable semble prometteur à ce stade. EF7 l' utilise également. Le problème, c'est que je ne sais pas et ne peux pas comprendre comment l'utiliser. Il n'y a presque rien sur le site Web qui indique à quiconque comment utiliser Ix.Net . Il y a une extension ToAsyncEnumerable que je peux utiliser sur les objets IEnumerable , mais cela ne ferait rien de manière asynchrone (ou le fait-il ??). Un autre inconvénient est que, vu la signature ci-dessous:

IAsyncEnumerable GetPersons();

Comme cette fonction ne renvoie pas la tâche, je ne peux pas utiliser async / wait dans le bloc de fonction.

Par contre, mon instinct me dit que je devrais rester en utilisant la Task<IEnumerable<T>> . Bien entendu, cela pose également des problèmes. EF n'a pas de méthode d'extension qui retourne ce type. Il a une méthode d'extension ToArrayAsync et ToListAsync mais cela nécessite bien sûr que vous ToArrayAsync ToListAsync dans la méthode car la Task<T> n'est pas covariante. C'est potentiellement un problème parce que cela crée une opération supplémentaire qui pourrait être évitée si je retournais simplement l'objet Task .

Ma question est la suivante: dois-je continuer à utiliser IAsyncEnumerable (préféré) ou dois-je tout remettre dans la Task<IEnumerable<T>> (non préféré)? Je suis également ouvert à d'autres suggestions.

Réponse populaire

IAsyncEnumerable avec IAsyncEnumerable . Il vous permet de garder vos opérations à la fois asynchrones et paresseuses.

Sans cela, vous devez renvoyer la Task<IEnumerble> ce qui signifie que vous chargez tous les résultats en mémoire. Cela signifie dans de nombreux cas interroger et conserver plus de mémoire que nécessaire.

Le cas classique est d'avoir une requête que l'utilisateur appelle Any . S'il s'agit de la Task<IEnumerable> , tous les résultats seront d'abord chargés en mémoire, et si le chargement est IAsyncEnumerable un résultat suffit.

Il est également intéressant de noter qu'avec la Task<IEnumerable> vous devez conserver l'ensemble du résultat en même temps, tandis qu'avec IAsyncEnumerable vous pouvez "diffuser" les résultats plusieurs fois à la fois.

De plus, c'est la direction que prend l'écosystème. Il a été ajouté par extension réactive, par une nouvelle bibliothèque suggérée par Stephen Toub cette semaine et sera probablement pris en charge dans la prochaine version de C # en mode natif .



Sous licence: CC-BY-SA with attribution
Non affilié à Stack Overflow
Est-ce KB légal? Oui, apprenez pourquoi
Sous licence: CC-BY-SA with attribution
Non affilié à Stack Overflow
Est-ce KB légal? Oui, apprenez pourquoi