0

在我的库中,我使用SynchronizationContext使我能够轻松地在 GUI 线程上引发事件,无论该库是在 Windows 窗体还是 WPF 应用程序中使用。如果我的类是在后台线程上创建的,则 SynchronizationContext 为空,因此我直接引发事件。

例如:

    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 网站中为空。如果 SynchronizationContext 是 AspNetSynchronizationContext 的一个实例,我需要一种不使用它的方法,尽管这样做会很麻烦,因为我没有引用 System.Web,而且它也不是公开可见的类型。

我的问题是,确定我是否在具有 GUI(例如 WinForms、WPF、WinRT)的应用程序中并且仅在该设置中使用 SynchronizationContext 的最佳方法是什么?

4

1 回答 1

1

这看起来像 ASP.NET 中的一个错误:如果在AspNetSynchronizationContext相应请求完成后使用 ,HttpApplication则清除其_context字段。然后它将这个 null 引用传递给ThreadContext构造函数,并且ThreadContext类上的方法尝试访问该字段的成员,从而导致NullReferenceException.

我知道他们在 4.5 中对该区域进行了一些更改,因此它可能已经修复。如果没有,可能值得在 Connect 上报告

作为一种解决方法,您可以尝试检查 current 的类型名称SynchronizationContext

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

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