2009-06-24 60 views
6

在WinForms中,您有Control.BeginInvoke(),這意味着您可以從後臺線程調用創建控件句柄的主UI線程的調用。馬歇爾手動線程

這很好,但是如何(在C#中)在兩個「標準」線程之間執行此操作?

我寫了一個服務總線,它有一個處理器線程來使用消息。我想要一個定時器來觸發,這會導致處理器線程執行某些操作,而不是在定時器線程中運行的代碼。

當然,我可以使用線程同步(Monitor/using() {...}),但想知道它是如何正常完成的。

回答

11

不幸的是,答案很難在這裏給出,因爲它高度依賴於線程的本質。

線程之間的封送並不神奇。有一個基本的機制可以做到。例如在WinForms中,Control.Invoke樣式函數通過消息傳遞工作。有一條消息發佈到UI線程,消息泵最終將輸出這條消息並將其轉換爲一個Marshal'd的調用。

爲了編組標準線程之間的調用,它必須具有一定的能力,通過該能力,它可以檢測元帥想要發生的調用,然後使該調用發生。這通常是通過某種消息傳遞完成的。

恕我直言,這樣做的最標準的方法是讓你的線程實現,提供並安裝一個SynchronizationContext。這是定義線程之間的Marshaling機制的更爲標準的方式。

+1

SynchronizationContext是我正在尋找的答案 - 謝謝! – 2009-06-24 14:11:18

1

Windows窗體運行message loop,這就是爲什麼你可以編組各種任務的UI線程 - 它會重複查找隊列中的消息,這可以通過線程邊界發送。

如果您想手動執行此操作,請創建自己的消息循環(對於一個或多個線程)或更簡單,請使用同步原語。對於這種情況,AutoResetEvent似乎是合適的。你只需要在正確的點上調用SetWaitOne方法,真的(當然要注意死鎖)。