Async awaitキーワードを正しく理解しているかどうかを誰かが確認してもらえますか? (CTPバージョン3を使用)
これまでのところ、メソッド呼び出しの前にawaitキーワードを挿入すると、基本的に2つのことが行われます。A。即時戻りとB.非同期メソッド呼び出しの完了時に呼び出される「継続」を作成します。いずれにしても、継続はメソッドのコードブロックの残りの部分です。
だから私が疑問に思っているのは、これらの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"));
一般的な考え方は正しいです-メソッドの残りの部分は、一連の並べ替えになります。
"高速パス"ブログ投稿 には、async
/await
コンパイラー変換の動作の詳細が記載されています。
私の頭の上の違い:
await
キーワードも「スケジューリングコンテキスト」の概念を利用します。スケジューリングコンテキストは、SynchronizationContext.Current
が存在する場合、TaskScheduler.Current
にフォールバックします。その後、継続がスケジューリングコンテキストで実行されます。したがって、より近い近似は、TaskScheduler.FromCurrentSynchronizationContext
をContinueWith
に渡し、必要に応じてTaskScheduler.Current
にフォールバックすることです。
実際のasync
/await
実装は、パターンマッチングに基づいています。これは、タスク以外のことを待機できる「待機可能」パターンを使用します。いくつかの例は、WinRT非同期API、Yield
、Rx observables、 GCにハードヒットしない特別なソケットawaitables などの特別なメソッドです。タスクは強力ですが、待ち受け可能なのはタスクだけではありません。
もう1つの些細な違いが思い浮かびます。awaitableが既に完了している場合、async
メソッドはその時点で実際には戻りません。同期的に継続します。したがって、TaskContinuationOptions.ExecuteSynchronously
を渡すようなものですが、スタック関連の問題はありません。
それは「本質的に」それですが、生成されたコードはそれだけではありません。生成されたコードの詳細については、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/
編集:質問から探しているものよりも詳細になる可能性が高いと思いますが、メソッドに複数の待機がある場合にどのように見えるか疑問に思っている場合は、ポスト#9でカバーされています:)
http://codeblog.jonskeet.uk/2011/05/30/eduasync-part-9-generated-code-for-multiple-awaits/