在我的库中,我使用SynchronizationContext使我能够轻松地在GUI线程上引发事件,无论该库是在Windows窗体还是WPF应用程序中使用。如果我的类是在后台线程上创建的,那么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)
我假设ASP.NET网站中SynchronizationContext
为空。我需要一种不使用SynchronizationContext的方法,如果它是AspNetSynchronizationContext的一个实例,虽然这样做会相当hacky,因为我没有引用System.Web而且它不是公开可见的类型。
我的问题是,确定我是否使用GUI(例如WinForms,WPF,WinRT)并且只在该设置中使用SynchronizationContext的最佳方法是什么?
答案 0 :(得分:1)
这看起来像是ASP.NET中的一个错误:如果在相应的请求完成后使用AspNetSynchronizationContext
,则HttpApplication
已清除其_context
字段。然后它将此null引用传递给ThreadContext
构造函数,ThreadContext
类上的方法尝试访问该字段的成员,从而导致NullReferenceException
。
我知道他们在4.5中对这个区域进行了一些更改,所以它可能已经修复了。如果没有,它可能值reporting on Connect。
作为解决方法,您可以尝试检查当前SynchronizationContext
的类型名称:
var context = SynchronizationContext.Current;
if (null != context && "AspNetSynchronizationContext" == context.GetType().Name)
{
context = null;
}
this.syncContext = context;