Ambas respuestas no mencionaron lo esperado Task.WhenAll
:
var task1 = DoWorkAsync();
var task2 = DoMoreWorkAsync();
await Task.WhenAll(task1, task2);
La principal diferencia entre Task.WaitAll
y Task.WhenAll
es que el primero se bloqueará (similar al uso Wait
en una sola tarea), mientras que el segundo no se podrá esperar, lo que devolverá el control a la persona que llama hasta que finalicen todas las tareas.
Más aún, el manejo de excepciones difiere:
Task.WaitAll
:
Al menos una de las instancias de la Tarea se canceló, o se lanzó una excepción durante la ejecución de al menos una de las instancias de la Tarea. Si se canceló una tarea, AggregateException contiene una OperationCanceledException en su colección InnerExceptions.
Task.WhenAll
:
Si alguna de las tareas suministradas se completa en un estado con error, la tarea devuelta también se completará en un estado con error, donde sus excepciones contendrán la agregación del conjunto de excepciones sin envolver de cada una de las tareas suministradas.
Si ninguna de las tareas suministradas falló pero al menos una de ellas se canceló, la tarea devuelta finalizará en el estado Cancelado.
Si ninguna de las tareas falló y ninguna de las tareas se canceló, la tarea resultante finalizará en el estado RanToCompletion. Si la matriz / enumerable suministrada no contiene tareas, la tarea devuelta pasará inmediatamente a un estado RanToCompletion antes de que se devuelva al llamante.
await Task.WhenAll(task1, task2);
?Task.WhenAll
no inicia las tareas por ti. Debe proporcionarlos "en caliente", lo que significa que ya comenzó.StartNew
tienen que ver las nuevas tareas y el giro con esperar asincrónicamente a todos?Podrías crear muchas tareas como:
fuente
La mejor opción que he visto es el siguiente método de extensión:
Llámalo así:
O con una lambda asíncrona:
fuente
Puede usar el
WhenAll
que devolverá un tipo de retornoTask
o elWaitAll
que no tiene retorno y bloqueará la ejecución de código adicional de manera simularThread.Sleep
hasta que todas las tareas se completen, cancelen o fallen.Ejemplo
Si desea ejecutar las tareas en un orden práctico, puede obtener inspiración de esta respuesta.
fuente
await
para cada operación y al mismo tiempo usasWaitAll
oWhenAll
? ¿No deberían estar las tareas en laTask[]
inicializaciónawait
?¿Desea encadenar los
Task
s, o pueden invocarse de forma paralela?Para encadenar
Solo haz algo como
y no olvide verificar la
Task
instancia anterior en cada una,ContinueWith
ya que podría tener errores.Para la manera paralela
El método más simple que encontré: de lo
Parallel.Invoke
contrario, hayTask.WaitAll
o incluso puedes usarWaitHandle
s para hacer una cuenta regresiva a cero acciones restantes (espera, hay una nueva clase:)CountdownEvent
, o ...fuente
Así es como lo hago con una matriz Func <> :
fuente
Otra respuesta más ... pero generalmente me encuentro en un caso, cuando necesito cargar datos simultáneamente y ponerlos en variables, como:
fuente
LoadCatsAsync()
yLoadDogAsync()
son solo llamadas a la base de datos, están vinculadas a IO.Task.Run()
es para trabajo vinculado a la CPU; agrega una sobrecarga innecesaria adicional si todo lo que está haciendo es esperar una respuesta del servidor de bases de datos. La respuesta aceptada de Yuval es la forma correcta para el trabajo vinculado a IO.He preparado un código para mostrarle cómo usar la tarea para algunos de estos escenarios.
fuente