¿Cómo devolvería correctamente una colección de objetos de forma asíncrona?

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

Pregunta

Necesito definir métodos en mi interfaz central que devuelvan listas. Mi proyecto se basa en gran medida en el uso de async / await, por lo que debo definir mis referencias / interfaces principales de la forma más asíncrona posible. También uso EF7 para mi capa de acceso a datos. Actualmente uso IAsyncEnumerable todas partes.

Actualmente estoy decidiendo si seguir usando IAsyncEnumerable o volver a usar la Task<IEnumerable<T>> . IAsyncEnumerable parece prometedor en este punto. EF7 también lo está utilizando . El problema es que no sé y no sé cómo usarlo. No hay casi nada en el sitio web que le diga a nadie cómo usar Ix.Net . Hay una extensión ToAsyncEnumerable que puedo usar en objetos IEnumerable , pero esto no haría nada de forma asíncrona (¿o sí?). Otro inconveniente es que dada la siguiente firma:

IAsyncEnumerable GetPersons();

Debido a que esta no es una función que devuelve Tarea, no puedo usar async / await dentro del bloque de funciones.

Por otro lado, mi instinto me dice que debo seguir usando la Task<IEnumerable<T>> . Esto, por supuesto, tiene sus problemas también. EF no tiene un método de extensión que devuelva este tipo. Tiene un método de extensión ToArrayAsync y ToListAsync , pero esto, por supuesto, requiere que usted espere dentro del método porque la Task<T> no es covariante. Esto potencialmente es un problema porque crea una operación adicional que podría evitarse si simplemente devolviera el objeto Task .

Mis preguntas son: ¿Debo seguir usando IAsyncEnumerable (preferido) o debo cambiar todo de nuevo a Task<IEnumerable<T>> (no preferido)? Estoy abierto a otras sugerencias también.

Respuesta popular

Yo iría con IAsyncEnumerable . Le permite mantener sus operaciones tanto asíncronas como perezosas.

Sin él, debe devolver la Task<IEnumerble> que significa que está cargando todos los resultados en la memoria. En muchos casos, esto significa consultar y conservar más memoria de la necesaria.

El caso clásico es tener una consulta que el usuario llama Any . Si es la Task<IEnumerable> cargará todos los resultados en la memoria, y si es IAsyncEnumerable cargar un resultado será suficiente.

También es relevante que con la Task<IEnumerable> debe mantener todo el conjunto de resultados en la memoria al mismo tiempo, mientras que con IAsyncEnumerable puede "transmitir" los resultados unos pocos a la vez.

Además, esa es la dirección hacia la que se dirige el ecosistema. Fue agregado por extensión reactiva, por una nueva biblioteca sugerida por Stephen Toub esta semana y probablemente será compatible en la próxima versión de C # de forma nativa .



Licencia bajo: CC-BY-SA with attribution
No afiliado con Stack Overflow
¿Es esto KB legal? Sí, aprende por qué
Licencia bajo: CC-BY-SA with attribution
No afiliado con Stack Overflow
¿Es esto KB legal? Sí, aprende por qué