待望の再開はどのように実装されていますか?
-
28-10-2019 - |
質問
私はC#5の非同期に関するEric Lippertのブログ投稿を読んでいます(パート4 特に関連性があります)そして、Anders PDC10がこのテーマについて話すのを見てきましたが、非同期方法からの継続が単一のスレッド付きコンテキストでどのように再開されるかは不明です。
どちらの情報源も、単一のスレッドUIループで非同期メソッドを使用して応答性を向上させ、アンダースの例では、非同期タスクが完了すると、メッセージポンプへのメッセージの追加によって継続がスケジュールされると述べています。
非同期方法は、コンテキスト固有のアクションのように見えるものを実行する必要があることを本当に知っていますか、それとも単純化でしたか?
より一般的には、単一のスレッドコンテキストで処理される非同期メソッドからの再開はどうすればよいでしょうか?単一のスレッド内でスケジュールする要件はありますか?
解決
タスクの継続は、継続をスケジュールする必要がある場所を把握しています - 例:「任意のスレッドプールスレッド」または「UIスレッド」。
この動作は「待望」によって決定されますが、実際にはC#コンパイラが責任を負うものの一部ではありません。コンパイラが電話するだけです BeginAwait
継続中に通過します。待望は、タスクがすでに同期して完了しているかどうか、または発信者が戻って継続を非同期に発生させるかどうかを示すブール値を返します。
したがって、今のところ、その決定は、によって返される待望で行われます TaskEx
- しかし、私はそれがすべてにバンドルされるのを見て驚かないでしょう Task
最終的。これは、同期のコンテキストのようなものを流れる可能性があります。これは、さらなるアクションをどのように処理するかを知っています。
どんな種類にもわかりません 本当に 検討しているシングルスレッドのコンテキスト...または、単一のスレッドで作業の大部分が発生する必要がある状況を考えていますか? 、IO完了ポートスレッドで処理され、応答 処理 UIスレッドに戻る)?
他のヒント
ジョンの答えはもちろん素晴らしいです。もう1つ追加するだけだと思いました。
ボタンをクリックしたときにコードを実行するフォームに1つのボタンを持つWinFormsアプリケーションを検討してください。
あなたがいるときにどうなりますか いいえ ボタンをクリックしますか?何もない。プロセスが存在し、コードは実行されていますが、何もしていないようです。実際、それがしているのは、UIスレッドでメッセージを処理し、それらのどれも興味深いものではないと判断することですが、面白いことをしているようには見えません。
ボタンをクリックすると、突然それらのメッセージの1つが興味深いものになり、メッセージポンプは、そのクリックイベントを表示したときに、コードを実行する必要があることを知っています。だからそうです。
Singrony-on-single-threadシナリオはまったく同じです。継続 - 「タスクが終了した後の対処方法」コードは、「タスクが終了した」イベントの「イベントハンドラー」です。タスクが終了すると、「ボタンを押します」と、UIスレッドのメッセージキューにメッセージが表示されます。 UIスレッドまたはI/O完了スレッドなどからそうするかどうかは関係ありません。 UIスレッドがそのメッセージの処理に移動すると、継続が呼び出されます。 UIスレッドがボタンクリックの処理に移動したときと同じように、クリックハンドラーが呼び出されます。