múltiples llamadas asíncronas paralelas con espera
Hasta donde yo sé, cuando el tiempo de ejecución encuentra la siguiente declaración, envuelve el resto de la función como una devolución de llamada al método que se invoca de forma asincrónica ( someCall()
en este ejemplo). En este caso anotherCall()
se ejecutará como una devolución de llamada a someCall()
:
await someCall();
await anotherCall();
Me pregunto si es posible hacer que el tiempo de ejecución funcione de esta manera: llame someCall()
de forma asíncrona y regrese inmediatamente al hilo de llamada, luego invoque anotherCall()
de manera similar (sin esperar someCall
a que se complete). Porque necesito que estos dos métodos se ejecuten de forma asincrónica y supongo que estas llamadas son solo llamadas de disparo y olvido.
¿Es posible implementar este escenario usando solo async
y await
(sin usar el mecanismo begin
/ antiguo end
)?
async/await incluye algunos operadores para ayudar con la composición paralela, como WhenAll
y WhenAny
.
var taskA = someCall(); // Note: no await
var taskB = anotherCall(); // Note: no await
// Wait for both tasks to complete.
await Task.WhenAll(taskA, taskB);
// Retrieve the results.
var resultA = taskA.Result;
var resultB = taskB.Result;
Probablemente la forma más sencilla sea hacer esto:
var taskA = someCall();
var taskB = someOtherCall();
await taskA;
await taskB;
Esto es especialmente bueno si quieres los valores de los resultados:
var result = await taskA + await taskB;
entonces no es necesario que lo hagas taskA.Result
.
TaskEx.WhenAll
Podría ser más rápido que dos esperas una tras otra. No lo sé, ya que no he investigado el rendimiento al respecto, pero a menos que vea un problema, creo que las dos esperas consecutivas se leen mejor, especialmente si desea los valores de los resultados.
El CTP asíncrono ya no es necesario siempre que esté utilizando .NET 4.5. Tenga en cuenta que el compilador implementa la funcionalidad asíncrona, por lo que las aplicaciones .NET 4 pueden usarla, pero se requiere VS2012 para compilarla.
TaskEx ya no es necesario. El CTP no pudo modificar el marco existente, por lo que utilizó extensiones para lograr cosas que el lenguaje manejaría en 5.0. Simplemente use Task directamente.
Por lo tanto, he reescrito el código (respondido por Stephen Cleary) reemplazando TaskEx con Task.
var taskA = someCall(); // Note: no await
var taskB = anotherCall(); // Note: no await
// Wait for both tasks to complete.
await Task.WhenAll(taskA, taskB);
// Retrieve the results.
var resultA = taskA.Result;
var resultB = taskB.Result;