2011-02-17 60 views
1

我有需要,因爲大多數人訂閱了該事件是控制到UI線程上的火事件的單例類的異步方法,但該方法的調用者不是控制。由於調用者不是一個總是控制,我不能將它傳遞迴調用回UI線程,所以相反,我使用AsyncOperation/SynchronizationContext在啓動後臺線程之前獲取當前線程上下文,然後在後臺線程中我打電話後,還挺像那麼......創建一個新的WindowsFormsSynchronizationContext

public void AsyncMethod() 
{ 
    AsyncOperation ao = AsyncOperationManager.CreateOperation(null); 
    // or SynchronizationContext ctx = WindowsFormsSynchronizationContext.Current; 

    ThreadPool.QueueUserWorkItem(delegate(objact state) 
    { 
     //do stuff 
     ao.Post(delegate(object state2) 
     { 
      // fire event 
     }, null); 
    }, null); 
} 

的問題是在於AsyncOperation有時給了我一個新的環境,或WindowsFormsSynchronizationContext爲null。我發現有其他人遇到同樣的問題,我認爲它涉及到下拉菜單項創建控件,這將發生在事件中。無論如何,我的問題是,如果WindowsFormsSynchronizationContext爲空,我可以創建一個新的調用Post on,並且將新的一個作爲UI線程的上下文,還是創建線程的上下文?

+0

不,這發生在從工作線程調用AsynchMethod()時。捍衛.NET的行爲,但證明它的工作。但是,它表明線程在你的應用程序失控。不要尋找解決方法(Application.OpenForms),找出線程調用此方法的原因。 – 2011-02-17 05:46:08

回答

1

如果這是一個用戶界面的應用程序,我會建議保持其在UI線程創建的類型控制的私有成員一單,並用它爲所有所調用:

  1. 您可以要求一個「初始化」的方法從一個UI線程調用(說Application.Run前右)和實例您同步控制有
  2. 或者,您可以創建同步控制時,第一次訪問你的單,或者通過檢查,如果當前線程運行消息循環(使用Application.MessageLoop),並且如果不在Application.OpenForms之一上調用控件創建。

拳頭的方法是更確定的,因此推薦。