Является ли 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/