¿Es posible usar Async cuando se usa ForEach? A continuación se muestra el código que estoy probando:
using (DataContext db = new DataLayer.DataContext())
{
db.Groups.ToList().ForEach(i => async {
await GetAdminsFromGroup(i.Gid);
});
}
Obtengo el error:
El nombre 'Async' no existe en el contexto actual
El método en el que se incluye la instrucción using se establece en async.
c#
async-await
James Jeffery
fuente
fuente
List.ForEach()
no es parte de LINQ.async
. ¡Han sido de gran ayuda!foreach
con unawait
en tu cuerpo de bucle.ForEach
solo toma un tipo de delegado síncrono y no hay sobrecarga al tomar un tipo de delegado asincrónico. Entonces, la respuesta corta es "nadie escribió un asincrónicoForEach
". La respuesta más larga es que tendrías que asumir algo de semántica; Por ejemplo, ¿deberían procesarse los artículos uno a la vez (comoforeach
) o simultáneamente (comoSelect
)? Si se trata de uno a la vez, ¿no serían las transmisiones asincrónicas una mejor solución? Si es simultáneo, ¿deberían los resultados estar en el orden del artículo original o en el orden de finalización? ¿Debería fallar en la primera falla o esperar hasta que todos se hayan completado? Etc.SemaphoreSlim
para acelerar las tareas asincrónicas.Este pequeño método de extensión debería brindarle una iteración asíncrona segura para excepciones:
Dado que estamos cambiando el tipo de retorno de la lambda de
void
aTask
, las excepciones se propagarán correctamente. Esto le permitirá escribir algo como esto en la práctica:fuente
async
debería ser antesi =>
ForEachAsync
es esencialmente un método de biblioteca, por lo que la espera probablemente debería configurarse conConfigureAwait(false)
.La respuesta simple es usar la
foreach
palabra clave en lugar delForEach()
método deList()
.fuente
Aquí hay una versión de trabajo real de las variantes de foreach asíncronas anteriores con procesamiento secuencial:
Aquí está la implementación:
¿Cuál es la diferencia clave?
.ConfigureAwait(false);
que mantiene el contexto del hilo principal mientras el procesamiento secuencial asincrónico de cada tarea.fuente
A partir de
C# 8.0
, puede crear y consumir transmisiones de forma asincrónica.Más
fuente
MoveNext
del enumerador. Esto es importante en los casos en que el enumerador no puede buscar el siguiente elemento instantáneamente y debe esperar a que haya uno disponible.Agregar este método de extensión
Y luego usa así:
fuente
El problema es que la
async
palabra clave debe aparecer antes del lambda, no antes del cuerpo:fuente
async void
. Este enfoque tiene problemas en torno al manejo de excepciones y a saber cuándo se completan las operaciones asincrónicas.