Ожидает ли Task.WhenAll в блоке C#. NET? - PullRequest
1 голос
/ 01 апреля 2020

Я немного запутался, когда дело доходит до асинхронных / ожидающих вещей. NET ...

Рассмотрим следующий метод:

public async Task DoSomething() {
   IEnumerable<Task> ts = GetSomeTasks(); // Some tasks that would do some random IO stuff, or whatever
   await Task.WhenAll(ts);
   Console.WriteLine("All tasks completed!");
}

Это вызов Console.WriteLine гарантированно будет выполнено после того, как задачи в ts ожидаются? Я думаю, что видел случаи, когда await, похоже, не «блокировался» таким образом, пока не был достигнут результат задачи. Какие правила применяются?

Ответы [ 3 ]

7 голосов
/ 01 апреля 2020

Гарантируется ли выполнение вызова Console.WriteLine после того, как задачи в TS ожидаются?

Да.

Я думаю, что ' Мы видели случаи, когда await, похоже, не блокировался таким образом, пока не был получен доступ к результату задачи.

Нет, это не так. Вы получите оператор только после оператора await (или, возможно, следующего выражения внутри оператора, например, для (await a) + (await b), только когда завершится ожидаемая вещь.

Обратите внимание, что Task.WhenAll сам по себе не является методом блокировки (в отличие от Task.WaitAll) - но он возвращает задачу, которая не завершается до тех пор, пока не будут выполнены все задачи, переданные в качестве аргументов.

4 голосов
/ 01 апреля 2020

Из Task.WhenAll Method Документация:

Создает задачу, которая завершится после завершения всех поставленных задач.

Первый пример на этой странице имеет следующий текст:

В следующем примере создается набор задач, которые проверяют URL-адреса в массиве. Задачи хранятся в коллекции List, которая передается методу WhenAll (IEnumerable). После вызова метода Wait убедитесь, что все потоки завершены ....

Это означает, что ответ на ваш вопрос будет Да - вызов Console.WriteLine будет произойдет только после того, как все задачи будут выполнены.

2 голосов
/ 01 апреля 2020

Да - вам гарантировано, что Console.WriteLine будет выполнено после выполнения всех задач в ts, потому что вы await его. Это задокументировано здесь: https://docs.microsoft.com/en-us/dotnet/api/system.threading.tasks.task.whenall?view=netframework-4.8

...