10

C# の新しい async/await 機能の CTP を確認する機会はありませんでしたが、次のような疑問がありました。

メッセージループとどのように統合しますか? 標準の Windows アプリケーション (Winforms、WPF) では、Dispatcherなどを使用して、アプリケーションのメッセージ ループにメッセージを送信することによって継続が呼び出されると思いますか?

標準の Windows メッセージ ループを使用していない場合はどうなりますか? たとえば、GTK# アプリケーションまたはコンソール アプリケーション (実際にこの機能がコンソール アプリケーションでまったく使用できる場合)。

これに関する情報をインターネットで検索しましたが、役に立ちませんでした。誰でも説明できますか?

4

2 に答える 2

6

System.Threading.SynchronizationContext.Currentを使用します。WPFとWinformsはどちらも、独自のバージョンのSynchronizationContextをインストールします。メッセージループを使用して、ワーカースレッドからメインUIスレッドにコールをマーシャリングします。それぞれDispatcher.Begin/InvokeおよびControl.Begin/Invoke()を使用します。

コンソールモードアプリでこれを行うのは簡単ではありません。メインスレッドには、再入可能性の問題を回避する安全な方法でマーシャリングされたメソッド呼び出しを挿入できる、明確に定義された「アイドル」状態がありません。あなたは確かにそれを追加することができますが、そうすることでメッセージループを再発明するでしょう。

于 2011-10-12T22:02:28.930 に答える
4

それはすべて、「待機者」が通過した継続で何をするかにかかっています。

BCLでのの実装でTask<T>は、現在の同期コンテキストを使用します(使用しないように要求しない限りConfigureAwait)。つまり、WPF/SilverLightではディスパッチャーを使用します。Windowsフォームでは、のようなものを使用Control.BeginInvokeし、スレッドプールスレッドでは、任意のスレッドプールスレッドで実行され続けます。重要なのは、await式の時点での現在のコンテキストであることに注意してください。これは、継続を実行するためにタスクがキャプチャするものだからです。

リンクされたブログ投稿(Mads Torgersenによる)は、すべてが内部でどのように機能するかを説明するのに最適です。私には、あなたも役立つと思われる一連のブログ投稿があります。

于 2011-10-12T21:58:58.903 に答える