Является ли Async ожидающим ключевое слово, эквивалентное продолжению с лямбдой?
Может кто-нибудь, пожалуйста, будьте любезны, чтобы подтвердить, правильно ли я понял ключевое слово Async? (Использование версии 3 CTP)
До сих пор я выяснил, что вставка ключевого слова await перед вызовом метода существенно делает 2 вещи, A. Он создает немедленное возвращение и B. Он создает "продолжение", которое вызывается после завершения асинхронного метода призывание. В любом случае продолжение - это остальная часть кода для метода.
Так что мне интересно, эти два бита кода технически эквивалентны, и если это так, то это в основном означает, что ключевое слово await идентично созданию ContinueWith Lambda (т.е.: в основном это ярлык компилятора для одного)? Если нет, каковы различия?
bool Success =
await new POP3Connector(
"mail.server.com", txtUsername.Text, txtPassword.Text).Connect();
// At this point the method will return and following code will
// only be invoked when the operation is complete(?)
MessageBox.Show(Success ? "Logged In" : "Wrong password");
VS
(new POP3Connector(
"mail.server.com", txtUsername.Text, txtPassword.Text ).Connect())
.ContinueWith((success) =>
MessageBox.Show(success.Result ? "Logged In" : "Wrong password"));
Ответы
Ответ 1
Общая идея правильная - остальная часть метода превращается в продолжение рода.
В сообщении "быстрый путь" сообщается о том, как работает трансформатор async
/await
.
Отличия, от верхней части головы:
Ключевое слово await
также использует концепцию "контекст планирования" . Контекст планирования SynchronizationContext.Current
, если он существует, возвращается на TaskScheduler.Current
. Продолжение выполняется в контексте планирования. Таким образом, более близкое приближение состояло бы в том, чтобы передать TaskScheduler.FromCurrentSynchronizationContext
в ContinueWith
, при необходимости вернуться на TaskScheduler.Current
.
Фактическая реализация async
/await
основана на сопоставлении с образцом; он использует "ожидаемый" шаблон, который позволяет ожидать других вещей помимо ожидаемых задач. Некоторыми примерами являются асинхронные API WinRT, некоторые специальные методы, такие как Yield
, Rx observables и специальные ожидания для сокетов, которые не сильно ударяют по GC.. Задачи мощные, но они не единственные ожидающие.
На ум приходит еще одно незначительное незначительное различие: если ожидаемое уже завершено, то метод async
фактически не возвращается в этой точке; он продолжается синхронно. Так что это вроде как передать TaskContinuationOptions.ExecuteSynchronously
, но без проблем, связанных с стеком.
Ответ 2
Это "по существу", что, но сгенерированный код делает нечто большее, чем просто это. Для получения более подробной информации о генерируемом коде, я настоятельно рекомендую серию Jon Skeet Eduasync:
http://codeblog.jonskeet.uk/category/eduasync/
В частности, сообщение # 7 попадает в то, что генерируется (как на CTP 2), и почему, так что, вероятно, отлично подходит для того, что вы ищете в данный момент:
http://codeblog.jonskeet.uk/2011/05/20/eduasync-part-7-generated-code-from-a-simple-async-method/
EDIT: Я думаю, что это скорее будет более подробно, чем то, что вы ищете от вопроса, но если вам интересно, как выглядят вещи, когда у вас есть несколько ожиданий в методе, описанных в статье № 9: )
http://codeblog.jonskeet.uk/2011/05/30/eduasync-part-9-generated-code-for-multiple-awaits/