2010-10-05 48 views
5

參考我需要從另一個線程(Excel的互操作)「送」一段代碼到UI線程來執行。通常你會在Form,它實現了ISynchronizeInvoke接口使用Invoke如何使用ISynchronizeInvoke不會對錶

public class MyForm : Form 
{ 
    ... 
    private void Button_Click(object sender, EventArgs e) 
    { 
     SomeExcelWorkbook.OnBeforeClose += delegate(ref bool Cancel) 
     { 
      this.Invoke(someCode); 
     }; 
    } 
} 

不幸的是,表單代碼和定義事件處理程序的代碼之間的抽象層,和我沒有一參照形式在這一點上:

public void CodeExecutedByUIThread() 
{ 
    ISynchronizeInvoke sync; 
    SomeExcelWorkbook.OnBeforeClose += delegate(ref bool Cancel) 
    { 
     sync.Invoke(someCode); 
    }; 
} 

當進入CodeExecutedByUIThread,我們仍然在UI線程,所以在理論上需要的一切應該在那裏。不幸的是,Form is the only class implementing that interface,是嗎?

如何從UI線程中得到一個ISynchronizeInvoke顯然Thread.CurrentThread不提供它...

或者有沒有辦法得到SynchronizationContext?我將如何檢索和使用它?

更新:哦,我看到,獲取SynchronizationContext對象看起來像SynchronizationContext.Current一樣簡單,它不需要任何對錶單的引用。所以我會更多地關於如何使用Google。

回答

2

一般來說,我認爲這兩者都不可能。

這似乎是一個明顯的答案,但我們在這種情況下使用的是在應用程序啓動時將SynchronizationContext和對錶單的引用(作爲ISynchronizeInvoke)存儲在靜態類中。

MainForm main = new MainForm(); 
EnvironmentService.UI = main; 
EnvironmentService.UIContext = SynchronizationContext.Current; 
Application.Run(main); 
+0

哦,我明白了,得到的SynchronizationContext對象看上去非常簡單,因此應不必表單的引用,甚至工作。 – chiccodoro 2010-10-05 14:42:35

+1

請小心,因爲在輔助線程上使用SynchronizationContext.Current將無法獲得所需的上下文,這就是爲什麼我建議在應用程序啓動時從主線程存儲它。 – matiash 2010-10-06 13:38:52

+0

好點,同時在網頁資源中也讀過這個警告。 – chiccodoro 2010-10-06 14:04:46

相關問題