2011-08-11 10 views
4

Dispatcher.BeginInvokeを使用してUIの更新がUIスレッド上で確実に行われることを確認しました。私はこの推論を理解している。なぜDispatcher.BeginInvokeを使用するのですか?

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

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

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

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

+0

下記の私の編集を参照してください – AnthonyWJones

答えて

3

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

しかし、UI要素から到着するイベントがUIスレッド上にあることを確認できます。

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

予防措置BeginInvokeを使用すると、呼び出したコードが呼び出されたUI操作コードと非同期で完了します。これは予測できない結果をもたらす可能性があります。あなたのコードを予測可能に動作させる方がはるかに優れています。正しいスレッド上でUIコンポーネントを呼び出す責任を負うコードにエラーを返すだけです。すべてのコードビハインドがUserControlPageなどのUIコンポーネントの一部として実行された後。

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

編集:あなたが使用して、どのようなスレッドAPIがコールされたされている非同期APIに依存して二次質問

の生意気な追加の答え。

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

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

0

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

+0

UI要素のイベントハンドラ(つまり、Clickedイベント)からUI要素の操作を直接行うことは安全です。これは非常にシンプルなので、私が言及した例で私は本当に混乱して、UIスレッド関連の例外がどのようにあるのかわかりませんでした。 – AlvinfromDiaspar

関連する問題