0

私のライブラリでは、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)

SynchronizationContextASP.NET Web サイトでは null になると想定していました。AspNetSynchronizationContext のインスタンスである場合、SynchronizationContext を使用しない方法が必要ですが、System.Web への参照がなく、一般に公開されているタイプではないため、これを行うのはかなり厄介です。

私の質問は、GUI (WinForms、WPF、WinRT など) を備えたアプリケーションにいるかどうかを判断し、その設定で SynchronizationContext のみを使用する最善の方法は何ですか?

4

1 に答える 1

1

これは ASP.NET のバグのようです。AspNetSynchronizationContext対応する要求が完了した後に が使用された場合、 はそのフィールドHttpApplicationをクリアします。_context次に、この null 参照をThreadContextコンストラクターに渡し、クラスのメソッドThreadContextがフィールドのメンバーにアクセスしようとするため、NullReferenceException.

4.5 でこの領域にいくつかの変更を加えたことを知っているので、既に修正されている可能性があります。そうでない場合は、おそらくConnect で報告する価値があります。

回避策として、現在の型名を調べてみてくださいSynchronizationContext

var context = SynchronizationContext.Current;
if (null != context && "AspNetSynchronizationContext" == context.GetType().Name)
{
   context = null;
}

this.syncContext = context;
于 2012-10-24T13:17:55.080 に答える