1. ホーム
  2. c#

[解決済み] Dispatcher.Invokeを使ってメインスレッド以外からWPFのコントロールを変更する

2023-04-22 22:49:34

質問

最近WPFでプログラミングを始めたのですが、以下のような問題にぶち当たりました。私は Dispatcher.Invoke() メソッドの使い方がわかりません。私はスレッドの経験があり、いくつかの簡単なWindowsフォームのプログラムを作ったことがありますが、そこでは単に

Control.CheckForIllegalCrossThreadCalls = false;

はい、かなりダサいのは分かっていますが、これらは単純なモニタリング・アプリケーションでした。

実際、私は今、バックグラウンドでデータを取得するWPFアプリケーションを作っています。私はデータを取得するための呼び出し(Webサーバーから)を行うために新しいスレッドを開始し、今私はそれをWPFフォームに表示したいのです。問題は、このスレッドからコントロールを設定することができないことです。ラベルや何かさえも。どのようにこれを解決することができますか?

回答コメント

@Jalfp です。

では、データを取得するときに 'new tread' でこの Dispatcher メソッドを使用するのでしょうか?それとも、バックグラウンドワーカーにデータを取得させ、それをフィールドに入れ、このフィールドが埋まるまで待つ新しいスレッドを開始し、取得したデータをコントロールに表示するためにディスパッチャーを呼び出すべきですか?

どのように解決するのですか?

まず最初に、Dispatcherは長いブロッキング処理(WebServerからデータを取得する、など)を実行するようには設計されていないことを理解する必要があります。UIスレッドで実行される操作(プログレスバーの値の更新など)を実行したい場合に、Dispatcherを使用することができます。

できることは、バックグラウンドワーカーでデータを取得し、ReportProgressメソッドを使用してUIスレッドに変更を伝搬させることです。

もし本当にDispatcherを直接使う必要があるなら、それはとても簡単です。

Application.Current.Dispatcher.BeginInvoke(
  DispatcherPriority.Background,
  new Action(() => this.progressBar.Value = 50));