2012-10-24 25 views
0

在我的庫中,我使用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的最佳方法?

回答

1

這看起來像在ASP.NET中的錯誤:如果相應的請求完成後使用AspNetSynchronizationContextHttpApplication已經清除了_context場。然後它將此空引用傳遞給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; 
+0

感謝,這是指着我沿着正確的線路。該請求幾乎可以肯定已經完成,因爲我的音樂庫是用於音頻播放的,所以事件可能在播放開始後幾分鐘被觸發(不確定人們爲什麼要在他們的網絡服務器上播放音頻,但這就是我的一些用戶在做)。我想我必須使用你的解決方法,除非有更好的方法來知道我是否在ASP.NET應用程序中。 –

+1

它絕對聽起來像你的用戶做錯了什麼 - 除非他們試圖嚇跑你的系統管理員,誰會聽到聲音播放?服務器是否有聲卡?他們可能希望聲音在*客戶*上播放,並且不瞭解其差異。你可能想要檢查'Environment.UserInteractive',並且拋出一個異常,或者如果它返回'false'就什麼也不做。 –

+0

是的,這是一個奇怪的要求,但我不時會讓人們試圖做到這一點。 'Environment.UserInteractive'看起來對我來說也是有用的。 –

相關問題