Задачи параллельно, используя C#. Я делаю это правильно? - PullRequest
1 голос
/ 18 февраля 2020

Я уже искал и читал о, я просто хочу убедиться, что я прав. У меня есть три метода, которые я хочу запустить параллельно, и я хочу убедиться, что все они выполнены, прежде чем продолжить. Все они асин c, и этот код находится внутри метода асин c. Я сделал это:

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(){...}

Это правильно?

Ответы [ 2 ]

4 голосов
/ 18 февраля 2020

Task.WaitAll блокируется синхронно, поэтому вы можете использовать Parallel.Invoke, если это предусмотрено:

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

Это работает до тех пор, пока сами методы methodX не являются асинхронными. Parallel.ForEach не работает с асинхронными c действиями.

Если вы хотите ждать асинхронного завершения задач, вы должны использовать Task.WhenAll:

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

await Task.WhenAll(tasks);
3 голосов
/ 18 февраля 2020
public async Task SomeProcess()
{
    //.. some code    

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

Используйте Task.WhenAll, который возвращает новый Task, который завершается после завершения всех предоставленных задач.

Вам не нужно создавать массив вручную, потому что Task.WhenAll принимает params Task[].

Использование Task.WaitAll, как вы пытались, блокирует текущий поток до завершения задач, что делает метод синхронным.

Кроме того, это может вызвать взаимные блокировки в зависимости от контекст синхронизации вашего приложения, так как method1 / method2 / method3 может попытаться возобновить работу в потоке, заблокированном WaitAll.

...