在我的庫中,我使用SynchronizationContext使我能夠輕鬆地在GUI線程上引發事件,無論該庫是在Windows窗體還是WPF應用程序中使用。如果我的類是在後臺線程上創建的,則SynchronizationContext爲null,因此我直接引發該事件。如何僅在客戶端應用程序中使用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網站中。如果它是AspNetSynchronizationContext的一個實例,我需要一種不使用SynchronizationContext的方法,儘管這樣做會相當黑客,因爲我沒有引用System.Web,並且它不是公開可見的類型。
我的問題是,什麼是確定我是否在具有GUI的應用程序(例如WinForms,WPF,WinRT)中並且只在該設置中使用SynchronizationContext的最佳方法?
感謝,這是指着我沿着正確的線路。該請求幾乎可以肯定已經完成,因爲我的音樂庫是用於音頻播放的,所以事件可能在播放開始後幾分鐘被觸發(不確定人們爲什麼要在他們的網絡服務器上播放音頻,但這就是我的一些用戶在做)。我想我必須使用你的解決方法,除非有更好的方法來知道我是否在ASP.NET應用程序中。 –
它絕對聽起來像你的用戶做錯了什麼 - 除非他們試圖嚇跑你的系統管理員,誰會聽到聲音播放?服務器是否有聲卡?他們可能希望聲音在*客戶*上播放,並且不瞭解其差異。你可能想要檢查'Environment.UserInteractive',並且拋出一個異常,或者如果它返回'false'就什麼也不做。 –
是的,這是一個奇怪的要求,但我不時會讓人們試圖做到這一點。 'Environment.UserInteractive'看起來對我來說也是有用的。 –