私のライブラリでは、SynchronizationContextを使用して、ライブラリが Windows フォームまたは WPF アプリで使用されているかどうかにかかわらず、GUI スレッドでイベントを簡単に発生できるようにします。クラスがバックグラウンド スレッドで作成された場合、SynchronizationContext は null なので、イベントを直接発生させます。
例えば:
private void RaisePlaybackStoppedEvent()
{
EventHandler handler = PlaybackStopped;
if (handler != null)
{
if (this.syncContext == null)
{
handler(this, EventArgs.Empty);
}
else
{
this.syncContext.Post(state => handler(this, EventArgs.Empty), null);
}
}
}
これは問題なく動作しますが、ASP.NET アプリケーションで問題が発生するというユーザー レポートがありました。
System.NullReferenceException was unhandled
Message=Object reference not set to an instance of an object.
Source=System.Web
StackTrace:
at System.Web.HttpApplication.ThreadContext.Enter(Boolean setImpersonationContext)
at System.Web.HttpApplication.OnThreadEnterPrivate(Boolean setImpersonationContext)
at System.Web.AspNetSynchronizationContext.CallCallbackPossiblyUnderLock(SendOrPostCallback callback, Object state)
at System.Web.AspNetSynchronizationContext.CallCallback(SendOrPostCallback callback, Object state)
at System.Web.AspNetSynchronizationContext.Post(SendOrPostCallback callback, Object state)
SynchronizationContext
ASP.NET Web サイトでは null になると想定していました。AspNetSynchronizationContext のインスタンスである場合、SynchronizationContext を使用しない方法が必要ですが、System.Web への参照がなく、一般に公開されているタイプではないため、これを行うのはかなり厄介です。
私の質問は、GUI (WinForms、WPF、WinRT など) を備えたアプリケーションにいるかどうかを判断し、その設定で SynchronizationContext のみを使用する最善の方法は何ですか?