2

「現在のSynchronizationContextは現在のスレッドのプロパティです」というフレーズを読んだので、少し混乱しています...

VS2010 の C# アプリ コードで入力すると、Thread.CurrentThread.Intellisense によって提供される選択肢のドロップダウン リストに、スレッドのコンテキスト関連のプロパティが見つかりません。

現在の同期コンテキストは " " を介して取得できることを知っています= SynchronizationContext.Current;。しかし、これは、並列スレッドやタスクなどで同時に実行される場合には、あまり幸運ではありません。

コンソールまたは WPF (*)アプリから、独自のメイン UI スレッドと TPL タスクでいくつかの Windows フォームを作成して起動するとします。

各 winform には独自のWindowsFormaSynchronizationContextが必要であり、WPF には独自のDispatcherSynchronizationContext ( SynchronizationContext クラスのサブクラス) インスタンスが必要であり、タスクは独自の同期コンテキストを持つThreadPoolで実行され、 LongRunning タスクはそのスレッド プールから実行される可能性があります。独自の同期コンテキスト...

では、なぜSynchronizationContextスレッドから定義できないのでしょうか? 「特定のスレッドから SynchronizationContext を取得する」という質問に対するすべての回答は、この可能性を否定する点で全会一致のようです...

最後になりましたが、「現在の SynchronizationContext は現在のスレッドのプロパティです」
というフレーズは正しいですか? 次に、さまざまな特定のスレッド インスタンスに対してこのプロパティの値を取得するにはどうすればよいですか?

(*)
最近、本質的に winform を使用する C# WPF アプリ コードが提供されました。

4

1 に答える 1

8

これは正確です。SynchronizationContext.Current プロパティは、現在のスレッドの m_ExecutionContext フィールドを使用します。これは Thread クラスのプライベート フィールドであるため、IntelliSense ドロップダウンに表示されません。

そのように動作することが重要です。デフォルトの SynchronizationContext は何も同期しません。その Post() メソッド ターゲットは、スレッドプール スレッドで実行されます。ターゲット呼び出しを特定のスレッドにマーシャリングすることは、非常に簡単なことではありません。これには、ターゲット スレッドの助けが必要であり、生産者と消費者の問題に対する解決策を提供する必要があります。一般的な解決策は、スレッド セーフなキューからメッセージを取得するループです。Winforms または WPF アプリの UI スレッドが機能するのとまったく同じように、"メッセージ ループをポンピング" します。Application.Run() がそのループを開始します。

そのため、そのようなアプリの UI スレッドだけが、スレッドプール スレッドを使用しない同期プロバイダーをサポートして、Post() デリゲート ターゲットを実行できます。したがって、フォームまたはウィンドウを作成するとすぐに、Winforms と WPF は独自の同期プロバイダーをインストールします。また、UI スレッドで実行されるコードのみが、SynchronizationContext.Current プロパティからデフォルト以外のプロバイダーを認識します。

その結果、UI スレッドで UI スレッドへの呼び出しをマーシャリングする必要があるコードを初期化する必要があります。たとえば、BackgroundWorker の作成は UI スレッドで行う必要があります。または、TaskScheduler.FromCurrentSynchronizationContext で作成されたタスク。技術的には、UI を表示する複数のスレッドが存在する可能性があります。初期化コードが実行されるスレッドは、Post() デリゲート ターゲットが実行される場所を決定します。初期化コードがワーカー スレッドで実行されている場合、Post() ターゲットはスレッドプール スレッドで実行されます。UI スレッドで参照を取得していれば、Synchronization.Current オブジェクトへの参照をワーカー スレッドに渡すことができます。

于 2013-04-30T11:51:21.943 に答える