несколько параллельных асинхронных вызовов с ожиданием

StackOverflow https://stackoverflow.com/questions/5974635

Вопрос

Насколько я знаю, когда во время выполнения встречается приведенный ниже оператор, он оборачивает остальную часть функции в обратный вызов метода, который вызывается асинхронно (someCall() в этом примере).В этом случае anotherCall() будет выполнен как обратный вызов someCall():

    await someCall();
    await anotherCall();

Интересно, можно ли заставить среду выполнения работать следующим образом:вызов someCall() в асинхронном режиме и немедленно вернуться в вызывающий поток, а затем вызвать anotherCall() аналогично (не дожидаясь someCall завершить).Потому что мне нужно, чтобы эти два метода работали асинхронно, и предположим, что эти вызовы — это просто вызовы «запустил и забыл».

Можно ли реализовать этот сценарий, используя только async и await (не используя старый begin/end механизм)?

Это было полезно?

Решение

В состав async/await входит несколько операторов, помогающих с параллельной композицией, например: WhenAll и 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;

Другие советы

Самый простой способ, вероятно, сделать это:

var taskA = someCall();
var taskB = someOtherCall();
await taskA;
await taskB;

Это особенно приятно, если вам нужны результирующие значения:

var result = await taskA + await taskB;

так что тебе не нужно делать taskA.Result.

TaskEx.WhenAll может быть быстрее, чем два ожидания друг за другом.я не знаю, так как я не проводил исследование производительности, но если вы не видите проблемы, я думаю, что два последовательных ожидания читаются лучше, особенно если вам нужны значения результата.

Async CTP больше не нужен, если вы используете .NET 4.5.Обратите внимание, что функциональность асинхронности реализуется компилятором, поэтому приложения .NET 4 могут ее использовать, но для ее компиляции требуется VS2012.

TaskEx больше не нужен.CTP не мог изменить существующую структуру, поэтому использовал расширения для выполнения задач, которые язык мог обрабатывать в версии 5.0.Просто используйте Task напрямую.

Итак, я переписал код (на который ответил Стивен Клири), заменив TaskEx на 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;
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top