2009-05-25 6 views
5

問題は次のとおりです。オブジェクトがUIスレッドでインスタンス化されていることを確認する必要があります。そうでない場合は、例外がスローされます。しかし、メソッド内でUIスレッドで実行されているかどうかをチェックするにはどうすればよいですか?注:私はオブジェクトのコンストラクタに情報を渡したくありません。メソッドがデコードされた方法でUIスレッドで実行されるかどうかを調べるにはどうすればよいですか?

完璧な候補はDispatcherSynchronizationContext(SynchronizationContextのWPF実装)です。内部的に関連付けられているスレッドを参照するDispatcherへの参照を内部的に保持しますが、残念ながらそのフィールドはプライベートなので、アクセスできません。

答えて

8

通常、UIスレッドは1つしかありませんが、UIスレッドは多数あります。これは、WPFとWinFormsの両方に当てはまります。

これを達成するために私が見つけた最良の方法はSynchronizationContextです。 WPFとWinFormsはUIを実行しているすべてのスレッドでSynchronizationContextを確立します。これは、特定のUIモデルに縛られていない場合に使用する関数です。

public bool IsPossiblyUIThread() { 
    return SynchronizationContext.Current != null; 
} 

注:これは決して簡単ではありません。非UIコンポーネントがSynchronizationContextを確立する可能性があり、単純なワーカースレッドでtrueを返します。したがって、権威のない名前。

少しこれを行うより信頼できる方法は次のとおりです。しかし、実装するにはWPFの少なくとも一部を参照する必要があります。

public bool IsLikelyWpfUIThread() { 
    var context = SynchronizationContext.Current; 
    return context != null && context is DispatcherSynchronizationContext; 
} 
+0

はい、これが最善の方法です。本当にありがとう! –

2

​​あなたのコードがディスパッチャと同じスレッド上で実行される場合はtrueを返します。 Dispatcher/UIThreadが1つしかない場合には、これはうまくいくはずです。

+1

これは当てはまりますが、Dispatcherは常にそのスレッドが作成されたスレッドに関連付けられていることに注意してください。したがって、Dispatcher.CheckAccess()を使用しても、オブジェクトが別のスレッドで作成された場合はそれほど役に立ちません。 –

関連する問題