37

私はWPFアプリケーションを構築しています。サーバー側と非同期通信を行っており、クライアントの Prism でイベント集約を使用しています。これらの両方により、UI スレッドではない新しいスレッドが生成されます。これらのコールバックおよびイベント ハンドラー スレッドで "WPF 操作" を実行しようとすると、世界がバラバラになります。

最初に、サーバーからのコールバックでいくつかの WPF オブジェクトを作成しようとして問題に遭遇しました。スレッドは STA モードで実行する必要があると言われました。今、Prism イベント ハンドラーでいくつかの UI データを更新しようとしていますが、次のように言われました。

別のスレッドがこのスレッドを所有しているため、呼び出し元はこのスレッドにアクセスできません。

そう; WPF で物事を正しく行うための鍵は何ですか? この MSDN の投稿で WPF Dispatcher について調べました。私はそれを理解し始めていますが、私はまだ魔法使いではありません.

  1. UIスレッドで呼び出されるかどうかわからない何かを実行する必要がある場合、常に Dispatcher.Invoke を使用することが重要ですか?
  2. それが実際に UI スレッドで呼び出されたかどうかは重要ですか? とにかく Dispatcher.Invoke を実行しますか?
  3. Dispatcher.Invoke = 同期的に。Dispathcher.BeginInvoke = 非同期?
  4. Dispatcher.Invoke は UI スレッドを要求し、停止して待機しますか? それは悪い習慣であり、反応の悪いプログラムのリスクですか?
  5. とにかくディスパッチャーを取得するにはどうすればよいですか?Dispatcher.CurrentDispatcher は常に UI スレッドを表すディスパッチャを提供しますか?
  6. 複数の Dispatcher が存在しますか、それとも "Dispatcher" は基本的にアプリケーションの UI スレッドと同じですか?
  7. そして、BackgroundWorker との取引は何ですか? 代わりにいつこれを使用しますか? これは常に非同期だと思いますか?
  8. UI スレッドで (Invoked によって) 実行されるものはすべて STA アパートメント モードで実行されますか? つまり、STA モードで実行する必要がある場合、Dispatcher.Invoke で十分でしょうか?

私のために物事を明確にしたい人はいますか?関連する推奨事項などはありますか?ありがとう!

4

1 に答える 1

40

質問を 1 つずつ見ていきます。

  1. そうではありません。必要な場合にのみ UI スレッドを呼び出す必要があります。#2を参照してください。
  2. はい、それは問題です。すべてを自動的に行うべきではありませんInvoke。重要なのは、必要な場合にのみ UI スレッドを呼び出すことです。これを行うには、Dispatcher.CheckAccessメソッドを使用できます。
  3. それは正しいです。
  4. また、正しいです。はい、応答性の低いプログラムのリスクがあります。ほとんどの場合、重大なパフォーマンス ヒットは見られませんが (コンテキスト スイッチのミリ秒単位での話です)、Invoke必要な場合にのみ確認する必要があります。そうは言っても、ある時点でそれは避けられないので、いいえ、それが悪い習慣だとはまったく言えません。これは、時々遭遇する問題に対する 1 つの解決策にすぎません。
  5. 私が見たすべてのケースで、私は期限を迎えましDispatcher.CurrentDispatcherた。複雑なシナリオの場合、これでは不十分かもしれませんが、私は (個人的には) 見たことがありません。
  6. 完全に正しいというわけではありませんが、この考え方が害を及ぼすことはありません。このように言えば、 を使用して、アプリケーションの UI スレッドにDispatcher アクセスできます。しかし、それ自体は UI スレッドではありません。
  7. BackgroundWorker通常、時間のかかる操作があり、その操作をバックグラウンドで実行しながら応答性の高い UI を維持したい場合に使用されます。通常、Invoke の代わりに BackgroundWorker を使用するのではなく、BackgroundWorkerを Invoke と組み合わせて使用​​します。つまり、BackgroundWorker の一部の UI オブジェクトを更新する必要がある場合は、UI スレッドを呼び出して更新を実行し、元の操作に戻ることができます。
  8. はい。WPF アプリケーションの UI スレッドは、定義上、シングルスレッド アパートメントで実行する必要があります。

についてBackgroundWorkerは言いたいことがたくさんありますが、すでに多くの質問が寄せられていると思いますので、あまり詳しくは説明しません。興味がある場合は、BackgroundWorker クラスの MSDN ページを確認してください。

于 2010-03-04T21:39:15.997 に答える