Ya he buscado y leído, solo quiero asegurarme de tener razón. Tengo tres métodos que quiero ejecutar en paralelo, y quiero asegurarme de que todos se realicen antes de continuar. Todos son asíncronos, y este código está dentro de un método asíncrono. He hecho esto:

public async ProcessBegin() {
   //... some code

   await SomeProcess();
   await AnotherMethod().
}

public async SomeProcess() {
   //.. some code    

   var tasks = new Task[3];
   tasks[0] = method1();
   tasks[1] = method2();
   tasks[2] = method3();

   Task.WaitAll(tasks);
}

public async Method1(){...}
public async Method2(){...}
public async Method3(){...}

¿Es esto correcto?

1
Leandro Souza 18 feb. 2020 a las 14:51

2 respuestas

La mejor respuesta

Task.WaitAll se bloquea sincrónicamente, por lo que puede usar Parallel.Invoke si se pretende:

Parallel.Invoke(() => method1(), () => method2(), () => method3());

Esto funciona siempre que los métodos methodX en sí mismos no sean asíncronos. Parallel.ForEach no funciona con acciones asíncronas.

Si desea esperar a que las tareas se completen de forma asincrónica, debe usar Task.WhenAll:

var tasks = new Task[3];
tasks[0] = method1();
tasks[1] = method2();
tasks[2] = method3();

await Task.WhenAll(tasks);
4
mm8 18 feb. 2020 a las 12:01
public async Task SomeProcess()
{
    //.. some code    

    await Task.WhenAll(method1(), method2(), method3());
}

Utilice Task.WhenAll que devuelve un nuevo Task que se completa una vez que todas las tareas proporcionadas también se han completado.

No necesita crear la matriz manualmente porque Task.WhenAll acepta params Task[].

El uso de Task.WaitAll, como lo ha intentado, bloqueará el hilo actual hasta que se completen las tareas, por lo que el método se sincronizará.

Además, podría causar puntos muertos dependiendo del contexto de sincronización de su aplicación, ya que method1 / method2 / method3 puede intentar reanudar en el hilo bloqueado por WaitAll.

3
Johnathan Barclay 18 feb. 2020 a las 12:08