83

私が Async await キーワードを正しく理解しているかどうかを誰かが確認してくれませんか? (CTP のバージョン 3 を使用)

これまでのところ、メソッド呼び出しの前に await キーワードを挿入すると、基本的に A. 即時リターンが作成され、B. 非同期メソッド呼び出しの完了時に呼び出される「継続」が作成されるという 2 つのことが行われることがわかりました。いずれにせよ、継続はメソッドのコード ブロックの残りの部分です。

だから私が疑問に思っているのは、これら2つのコードは技術的に同等であり、もしそうなら、これは基本的に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"));
4

2 に答える 2

85

一般的な考え方は正しいです。メソッドの残りの部分は、一種の継続になります。

高速パス」のブログ投稿asyncには、 /awaitコンパイラ変換のしくみに関する詳細が記載されています。

私の頭の上からの違い:

このawaitキーワードは、「スケジューリング コンテキスト」の概念も利用します。スケジューリング コンテキストがSynchronizationContext.Current存在する場合は、 にフォールバックしTaskScheduler.Currentます。その後、継続がスケジューリング コンテキストで実行されます。したがって、必要に応じてフォールバックしてTaskScheduler.FromCurrentSynchronizationContextに渡します。ContinueWithTaskScheduler.Current

実際のasync/await実装はパターン マッチングに基づいています。タスク以外のことを待機できる「待機可能」パターンを使用します。いくつかの例として、WinRT 非同期 API、YieldRx オブザーバブル、およびGC をハードにヒットしない特別なソケット awaitableなどのいくつかの特別なメソッドがあります。タスクは強力ですが、待機できるのはタスクだけではありません。

もう 1 つの細かい違いが思い浮かびます。awaitable が既に完了している場合、asyncメソッドはその時点で実際には返されません。同期的に継続します。つまり、 を渡すようなものですTaskContinuationOptions.ExecuteSynchronouslyが、スタック関連の問題はありません。

于 2012-01-07T04:39:37.443 に答える
9

それは「本質的に」ですが、生成されたコードは厳密にはそれだけではありません。生成されたコードの詳細については、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/

編集:質問から探しているものよりも詳細である可能性が高いと思いますが、メソッドに複数の await がある場合にどのように見えるか疑問に思っている場合は、投稿 #9 で説明されています:)

http://codeblog.jonskeet.uk/2011/05/30/eduasync-part-9-generated-code-for-multiple-awaits/

于 2012-01-07T04:38:52.223 に答える