#asynchronous #multitasking #async-await #c#-5.0
#асинхронный #многозадачность #асинхронный-ожидание #c #-5.0
Вопрос:
Насколько я знаю, когда среда выполнения сталкивается с приведенным ниже оператором, она оборачивает остальную часть функции как обратный вызов метода, который вызывается асинхронно ( someCall()
в этом примере). В этом случае anotherCall()
будет выполнен обратный вызов someCall()
:
await someCall();
await anotherCall();
Интересно, возможно ли заставить среду выполнения работать следующим образом: вызывайте someCall()
асинхронно и немедленно возвращайтесь к вызывающему потоку, затем вызывайте anotherCall()
аналогично (не дожидаясь someCall
завершения). Потому что мне нужно, чтобы эти два метода выполнялись асинхронно, и предположим, что эти вызовы просто запускают и забывают вызовы.
Возможно ли реализовать этот сценарий, используя только async
и await
(не используя старый механизм begin
/ end
)?
Ответ №1:
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.Resu<
var resultB = taskB.Resu<
Комментарии:
1. Есть ли что-нибудь из этого для ECMAScript / Javascript?
2. @Azteca: Конечно, вы можете использовать
Promise.all
вместоTask.WhenAll
илиPromise.race
вместоTask.WhenAny
. Например.,await Promise.all([promiseA, promiseB]);
Ответ №2:
Вероятно, самый простой способ сделать это:
var taskA = someCall();
var taskB = someOtherCall();
await taskA;
await taskB;
Это особенно удобно, если вам нужны результирующие значения:
var result = await taskA await taskB;
так что вам не нужно делать taskA.Result
.
TaskEx.WhenAll
может быть быстрее, чем два ожидания друг за другом. я не знаю, поскольку я не проводил исследование производительности по этому поводу, но если вы не видите проблемы, я думаю, что два последовательных ожидания читаются лучше, особенно если вы хотите значения результата.
Комментарии:
1. Цитирую «Асинхронность в C # 5.0»: «Это опасный способ ожидания нескольких задач, если они могут вызывать исключения. Если обе операции генерируют исключение, первая
await
распространит свое исключение, что означает, чтоtaskB
никогда не ожидается. Его исключение не будет наблюдаться и, в зависимости от версии .NET и настроек, может быть потеряно или даже повторно подключено к неожиданному потоку, завершая процесс «.2. Так что вам лучше придерживаться
await Task.WhenAll(taskA, taskB);
Ответ №3:
Асинхронный CTP больше не нужен, если вы используете .NET 4.5. Обратите внимание, что функциональность async реализована компилятором, поэтому приложения .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.Resu<
var resultB = taskB.Resu<