4

Dispatcher.BeginInvoke を使用して、UI スレッドで UI の更新が確実に行われるようにする方法を見てきました (そして読んだこともあります)。私はこの理屈を理解しています。

しかし、ビュー コード ビハインドで、TextBlock の Text プロパティなどのプロパティの割り当てが、この Dispatcher.BeginInvoke で割り当てた場合にのみ安全であると宣言される例を見てきました。

質問 ビューのコード ビハインドから何かを操作している場合、それは UI スレッドで操作されていることを意味しませんか (BackgroundWorker または非同期サービス呼び出しを使用していないと仮定します)。

上記の例では、他のスレッドや非同期操作は使用されていません。

質問 2 非同期 Web サービス ハンドラーがあり、このハンドラー内から TextBlock の文字列を更新したい場合。TB の Text プロパティを直接割り当てることはできますか、それとも Dispatcher.BeginInvoke を使用する必要がありますか。このような UI 要素の直接操作よりもデータ バインディングを優先するため、通常はこれを行わないことに注意してください。

4

2 に答える 2

3

「UIスレッドで操作されていることを暗示していませんか」と尋ねます。非プライベート コード エントリ ポイントが非 UI スレッドで呼び出される可能性があることを Mike が指摘しているため、絶対的な保証を与えるものは何もありません。

ただし、UI 要素から到着するイベントが UI スレッド上にあることは確実です。

コード ビハインドが UI スレッドで確実に実行されるようにするための予防措置については、賢明ではないと思います。コードを正常に進行させるとどうなりますか。UI要素を実際に操作していないため、成功する可能性がありますが、害はありません。または、コードが続行され、例外がスローされます。それは悪いことですか?

予防策を使用するBeginInvokeと、呼び出された UI 操作コードと非同期で完了する呼び出しコードが発生します。これにより、追跡が困難な予測不可能な結果が生じる可能性があります。コードが予測どおりに動作するようにする方がはるかに優れています。正しいスレッドで UI コンポーネントを呼び出す責任があるコードにエラーを返すだけです。UserControl結局、分離コードはやなどの UI コンポーネントの一部として実行されPageます。

また、ランタイム、SDK、およびツールキットの既存の UI 要素は、予防的なスレッド切り替えを行わないことも考慮してください。

編集:二次的な質問の生意気な追加への答え

これは、使用している Async API と、API が呼び出されたスレッドによって異なります。

UI スレッドから非同期メソッドを呼び出すとWebClient、対応するイベントが UI スレッドでも発生します。同様に、WCF サービス クライアント クラスを使用している場合、UI スレッドで非同期操作が最初に呼び出されると、UI スレッドで Completed イベントが発生します。

ただし、WebRequest コンポーネント (または WCF の標準サービス インターフェイス) で Begin/End ペアを使用すると、操作の開始に使用された元のスレッドに関係なく、バックグラウンド スレッドでコールバックが実行されます。

于 2011-08-11T21:36:45.080 に答える
0

UI イベントにのみ応答する保護されたメソッドまたはイベント ハンドラーの場合は、ディスパッチャーがなくても安全です。ただし、何らかの方法で外部に公開される可能性のあるコードを使用している場合は、コードが実行される可能性のあるスレッドについて何も仮定しない方がよいでしょう。

于 2011-08-11T20:13:45.780 に答える