1

私はSilverlightアプリケーションを開発していますが、UIスレッドで実行された場合に例外をスローするメソッドがあります。これは、UIスレッドがフリーズするタイムアウトなしでAutoResetEvent.WaitOne()を使用するためです。
現在のスレッドがUIスレッドであるかどうかを検出するにはどうすればよいですか?

編集:
このメソッドは、UIコンポーネントではなく、クラスライブラリに存在することに注意してください。

4

1 に答える 1

1

( CheckAccess()関数をApplication.Current.Dispatcher使用して)を使用して、メインUIスレッドにいるかどうかを確認できます。

メインUIスレッドについて述べたことに注意してください。これは重要です。どのスレッドにもディスパッチャーを関連付けることができ*、複数のUIスレッドを持つことができるからです。より正確に言うと、あなたの質問は

現在実行されているコードがUIスレッドであるかどうかを確認するにはどうすればよいですか?

バックグラウンド(スレッドプール)スレッドとUIスレッドの(私が見た)唯一の実際の識別可能な違いはApartmentStateであるため、これは確実に不可能な場合があります-UIスレッドはSTAであり、スレッドで使用可能なスレッドプールはMTAです。ただし、これはSTAスレッドがUIスレッドであることを意味するものではありません。(誰かがここで決定的な何かをチップインしてくれてうれしいです)。おそらくあなたの解決策はそれを別の方法で見ることです-AutoResetEvent.WaitOne()呼び出しがMTAであるスレッドでのみ行われることを確認してください。

*this.Dispatcher.CheckAccess()バックグラウンドスレッドでコードを実行してみて、何が起こるかを確認してください。

編集:

これはSilverlightであるべきだと指摘してくれた@drowに感謝します... 上記の回答はWPFにも適用できるため、そのままにしておきます。@drowで説明されているように、SilverlightではスレッドのApartmentStateにアクセスする方法はなく、System.Threading.Thread.CurrentThreadを使用している場合はディスパッチャーを使用できません。

したがって、別のオプションとして、 falseDeployment.Current.Dispatcher.CheckAccess()を返すかどうかを確認できます。falseを返す場合は、バックグラウンドスレッド(つまり、メインUIスレッドではない)を使用しています。私はこれをテストしました、そしてそれはうまく働きます。

于 2011-04-13T11:06:46.520 に答える