私は.NET Frameworkで提供されている非同期機能に不慣れです
だから私の理解ではasyncキーワードによって提供される利点はスレッドが非同期メソッドを呼び出すとき、それは待機ポイントに戻って正しく実行を再開できることです。
私の質問は、その時点から戻った後、スレッドは何をしているのでしょうか。それはスレッドプール内の他のタスク項目を実行するために使用することができます、もしそうなら、まだコンテキストスイッチがなければなりませんか?もしそうでなければ、なぜそこにただスピンしないのですか?
===== そのため、async関数の終了していない部分を引き継ぐスレッドが他にもあるでしょう。これらの状態はどこに格納されているのでしょうか。そして他のスレッドはどのようにそれらの状態をとるのか
あなたのコードがawait
式(awaitableが同期的に完了しなかったと仮定して)、あなたが書いたかのように、制御は呼び出しメソッドに戻ります。return;
。
(を返しますTask<T>
呼び出し側が非同期部分の完了を待つために使用できること)
呼び出し元のメソッドは、実行されるまで実行を続けます。それ戻ります(通常はすぐに戻りますawait
s(返されたタスク)など、コールスタックの(ユーザーに面する部分)の先頭に到達するまで続きます。
呼び出しスタックの一番上に達すると、そのスレッドは自然に行うことは何でもします。
それがUIスレッドであれば、それはメッセージループに戻り、UIを反応させ続けます。
ThreadPoolスレッド(またはASP.Netワーカースレッド)の場合は、プールに戻り、(同期的に)次の作業を待ちます。
それが「生の」スレッド(コンソールアプリケーションのメインスレッド、またはnew Thread()
、それは終了します。
Task.ContinueWith()
これはクロージャのようなもので現在の状態を捉えるコールバックを取ります。見るmsmvps.com/blogs/jon_skeet/archive/tags/Eduasync/default.aspx - SLaks
はい、スレッドは戻り、他の作業を行うことができます。
はどうかと言うとwhy not just spin there
それは他の仕事をすることができるからです。スレッドに作業の機会があるときにスレッドを強制的にアイドル状態にしておくことに意味はありません。
どのスレッドが実際に作業を続けるのか気にしないのであれば、次のようにTask.ConfigureAwaitを使用できます。
await foo.DoSomethingAsync().ConfigureAwait(continueOnCapturedContext: false);
ConfigureAwait()
スレッドが次に行うこととは無関係です。 - SLaks