C# 如何仅在客户端应用中使用SynchronizationContext

C# 如何仅在客户端应用中使用SynchronizationContext,c#,asp.net,synchronizationcontext,C#,Asp.net,Synchronizationcontext,在我的库中,无论该库是否正在Windows窗体或WPF应用程序中使用,我都可以使用a轻松地在GUI线程上引发事件。如果我的类是在后台线程上创建的,那么SynchronizationContext为null,因此我直接引发事件 例如: private void RaisePlaybackStoppedEvent() { EventHandler handler = PlaybackStopped; if (handler != null)

在我的库中,无论该库是否正在Windows窗体或WPF应用程序中使用,我都可以使用a轻松地在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)
我曾假设在ASP.NET网站中,
SynchronizationContext
将为空。如果SynchronizationContext是AspNetSynchronizationContext的实例,我需要一种不使用SynchronizationContext的方法,尽管这样做会很麻烦,因为我没有对System.Web的引用,而且它也不是公开可见的类型


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

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

我知道他们在4.5中对这个区域做了一些更改,所以它可能已经被修复了。如果不是的话,这可能是值得的

作为一种解决方法,您可以尝试检查当前同步上下文的类型名称:

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

this.syncContext = context;

谢谢,这给我指明了正确的方向。请求几乎肯定已经完成,因为我的库是用于音频播放的,所以该事件可能在播放开始几分钟后触发(不确定人们为什么希望在他们的Web服务器上播放音频,但我的一些用户就是这么做的)。我想我必须使用你的变通方法,除非有更好的方法知道我是否在ASP.NET应用程序中。听起来你的用户肯定做错了什么-除非他们试图吓唬你的系统管理员,谁会听到声音?服务器甚至有声卡吗?他们可能希望在客户机上播放声音,但不理解其中的区别。您可能需要检查
环境。UserInteractive
,如果返回
false
,则抛出异常或不执行任何操作。是的,这是一个奇怪的请求,但我确实经常有人尝试这样做
Environment.UserInteractive
看起来对我也很有用。