1. ホーム
  2. c#

[解決済み] Async awaitキーワードはContinueWith lambdaと同等か?

2023-06-13 02:50:35

質問

私が Async await キーワードを正しく理解しているかどうか、どなたか親切な方に確認していただけないでしょうか。(CTPのバージョン3を使用しています)

A. それは即時リターンを作成し、B. それは非同期メソッドの呼び出しの完了時に呼び出される "continuation" を作成することです。いずれにせよ、継続はメソッドのコードブロックの残りとなります。

もしそうなら、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 キーワードはまた、quot;scheduling context" という概念を利用します。スケジューリングコンテキストは SynchronizationContext.Current で、存在すれば TaskScheduler.Current . そして、スケジューリングされたコンテキストで継続が実行されます。ですから、より近い近似値としては TaskScheduler.FromCurrentSynchronizationContextContinueWith にフォールバックします。 TaskScheduler.Current に戻る。

実際の async / await の実装はパターンマッチに基づいています; それはタスク以外のものを待ち受けることを可能にする "awaitable" パターンを使用します。例としては、WinRTの非同期APIや、以下のような特殊なメソッドなどがあります。 Yield のような特別なメソッド、Rx observables、そして GCに負担をかけない特殊なソケット待ち受け . タスクは強力ですが、それだけがawaitablesではありません。

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