私はSilverlightアプリケーションを開発していますが、UIスレッドで実行された場合に例外をスローするメソッドがあります。これは、UIスレッドがフリーズするタイムアウトなしでAutoResetEvent.WaitOne()を使用するためです。
現在のスレッドがUIスレッドであるかどうかを検出するにはどうすればよいですか?
編集:
このメソッドは、UIコンポーネントではなく、クラスライブラリに存在することに注意してください。
私はSilverlightアプリケーションを開発していますが、UIスレッドで実行された場合に例外をスローするメソッドがあります。これは、UIスレッドがフリーズするタイムアウトなしでAutoResetEvent.WaitOne()を使用するためです。
現在のスレッドがUIスレッドであるかどうかを検出するにはどうすればよいですか?
編集:
このメソッドは、UIコンポーネントではなく、クラスライブラリに存在することに注意してください。
( 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スレッドではない)を使用しています。私はこれをテストしました、そしてそれはうまく働きます。