1

ここでの問題は少し抽象的なものです。バックグラウンドスレッドがいくつかのUI要素を更新することは誰もが知っています。

Dispatcher.Invoke()

唯一のオプションです(そうですか?)。ただし、Dispatcher.Invoke()自体は、更新タスクをUIスレッドに委任します。次のようなシナリオを検討します。

  • バックグラウンドスレッドがUIを更新することが多すぎます。
  • 数十のスレッドが同じUIを更新します。

Dispatcherオブジェクトは更新タスクをUIスレッドに委任し続け、UIスレッドが遅くなる可能性があります。考えられる解決策は何ですか?スレッドモデルがWPFのモデルと非常に似ているWindowsフォームでこのような問題をどのように解決できますか?WPFは他のスレッド技術を提供しますか?

よろしく、

4

3 に答える 3

2

メッセージ(APC、デリゲートなど)を処理できる速度よりも速く投稿して、GUIスレッドの入力キューをオーバーロードすると、WPF/フォームなどに関係なく問題が発生します。

複数のGUI状態が頻繁に更新されるため、すべての変更を投稿するとキューが過負荷になり、表示が急速に変化して人間が読めなくなる場合は、非GUIスレッドが最新のデータを保存するのが一般的です。共有オブジェクトおよびGUIスレッドがタイマーを使用してより適切な間隔でデータを表示するため。

すべてのデータを損失なく表示する必要がある場合(たとえば、GUIメモまたはHTMLレンダラーは送信されたすべてのものを表示する必要があります)、メッセージキューの過負荷を防ぐために、オブジェクトプールを介した適切なフロー制御やデータの遅延投稿が必要になる場合があります。

「ここでの問題は少し抽象的なものです」-その抽象的なものではありません。私は忙しいアプリで何度もこの問題にぶつかりました。私のものでは、GUIがブロックされているために処理および解放されていない投稿されたメッセージでスレッド間通信プールからのすべてのオブジェクトがスタックするため、入力キューの過負荷が長引くとデッドロックが発生する傾向があります-オブジェクトを取得しようとしています空のプールから:((

于 2012-03-16T10:18:14.227 に答える
1

まず第一に、人間の目が気付かないことが多いUIを更新する必要がある理由は、理想的には、進行状況が1秒のギャップで更新されたとしても許容されます。たとえば、ファイルを書き込んでいて、おそらく30ミリ秒ごとに4Kバイトを書き込んでいる場合、人間の目は気付かず、ミリ秒単位の画面のパフォーマンスは気にしません。

UIスレッドをビジーにするだけでなく、Dispatcher.Invokeは実行が終了するまで他のスレッドもブロックしますが、Dispatcher.BeginInvokeは他のスレッドをブロックしません。

UIスレッドは、いくつかのラベルを更新するか、画面上で進行する場合、おそらく数ミリ秒で更新を完了します。

UIは非常に複雑であり、複数のスレッドからのアクセスを許可するとデッドロックが発生し、アプリが応答しなくなる可能性があるため、WPFも他のプラットフォームもより良い方法を提供できません。これが、Java、Objective-c、または任意のUIフレームワークを問わず、すべてのプラットフォームでUIの作成者スレッドでのみUIを更新する必要がある理由です。

ただし、WPFには、ウィンドウごとに複数のUIスレッドを作成する方法もありますが、それも非常に複雑です。ゲームなどは、ダブルバッファリングと呼ばれるものを使用します。この場合、前のバッファが画面上で更新されている間に、バックグラウンドで1つのバッファを別のスレッドで処理します。

于 2012-03-16T10:32:51.447 に答える
1

Invokeシンプルで、UIの更新には使用しないでください。代わりに、ワーカースレッドに「UIスレッドに送信する」必要のあるデータをキューやリストなどの共有データ構造に公開させ、UIスレッドに特定の間隔でポーリングさせます。これにはいくつかの利点があります。

  • それは、UIとワーカースレッドの間の緊密な結合を壊しますInvoke
  • UIスレッドは、UIコントロールがいつ更新されるかを指示します...実際にそれについて考えるときのようになります。
  • InvokeまたはBeginInvokeワーカースレッドから使​​用された場合のように、UIメッセージキューをオーバーランしたり、他のメッセージを使い果たしたりするリスクはありません。
  • ワーカースレッドは、の場合のようにUIスレッドからの応答を待つ必要はありませんInvoke
  • UIスレッドとワーカースレッドの両方でスループットが向上します。
  • InvokeBeginInvoke高価な操作です。

私はいつもこれについてハープしていることを知っていますがInvoke、多くの状況で実際にもっと良い選択肢があります。のようInvokeなマーシャリング技術は、かなり使い古されています。

于 2012-03-16T13:20:35.330 に答える