2010-08-13 55 views
8

有什麼辦法讓委託在特定線程上運行?在特定線程上調用委託C#

說我有:

CustomDelegate del = someObject.someFunction; 
Thread dedicatedThread = ThreadList[x]; 

我能有一個一致的背景下長期運行的線程並調用我自己的代表,每當我需要它。它必須每次都是相同的線程。

[編輯]

爲什麼我想這是一個專門的線程的原因是時間是我INTEN在其上運行的委託後y毫秒掛起線程,並繼續當我運行的線程另一位代表就此。我看到這是不可能的。我將有一個委託隊列,讓線程的主函數從中讀取並運行。

爲了澄清一個具體的例子,我有一個玩家線程的遊戲系統。我希望每個playerthread都能爲其上的遊戲事件運行事件處理程序。如果事件處理程序花費太多時間,我希望能夠暫停該特定播放器,直到下一個事件掛起其線程爲止。

因此,有一個專用的線程可以運行多個事件處理程序,我可以暫停某個特定的玩家的AI,以防它被竊聽或時間過長。

回答

3

我認爲最好的解決方案是使用Task對象並將它們排隊到運行單個線程的StaThreadScheduler

或者,您可以使用ActionThread中的Nito.Async創建一個具有Action代表的內置隊列的正常線程。

但是,這些都不能直接解決另一個需求:「暫停」一個動作並繼續執行另一個動作的能力。要做到這一點,你需要在每個動作中都撒上「同步點」,並有一種方法來保存它的狀態,重新排列它,並繼續下一個動作。

所有這些複雜性都非常接近線程調度系統,所以我建議退後一步並做更多的重新設計。您可以允許每個動作排隊到ThreadPool(我建議每個動作都是Task對象)。你仍然需要撒上「同步點」,但不是保存狀態並重新排隊它們,而只需暫停(阻止)它們。

+0

謝謝你指出ActionThread,看起來非常有用。我需要封裝外部代碼,在線程中我幾乎沒有任何控制權。我所擁有的只是代表外部代碼。如果我可以確保該對象在一個特定的線程中,我可以通過暫停該線程來「暫停」該對象。我不認爲線程池將允許我很好地「暫停」對象。 – Raynos 2010-08-14 08:10:39

+0

警告:通過掛起/恢復線程可能(甚至可能)意外造成死鎖。如果可能,請更改外部代碼。如果這是不可能的,那麼考慮使用線程優先級而不是掛起/恢復。 – 2010-08-14 10:23:30

1

通常,我會建議只使用線程池或BackgroundWorker類 - 但這些不能保證任何特定線程上都會發生工作。目前還不清楚爲什麼你關心哪個線程運行的作品,但假設它確實有關係...

你將不得不通過Delegate對象通過某種共享內存,如隊列。後臺線程必須觀察這個隊列,並在它們存在時將其取出,然後執行它們。

如果事實證明,線程池是可以接受的運行你的代碼,你總是可以使用委託的BeginInvoke方法可以這樣做:

// wrap your custom delegate in an action for simplicity ... 
Action someCode =() => yourCustomDelegate(p1, p2, p3, ...); 
// asynchronously execute the currying Action delegate on the threadpool... 
someCode.BeginInvoke(someCode.EndInvoke, action); 
2

不幸的是真的有什麼內置做到這一點在任何通用線程上。您可以通過創建一個包裝一個線程並實現的類來實現此目的。一個簡單的方法是在LBushkin提到的專用線程上創建一個事件處理隊列。我建議使用Queue<Action>類並直接調用Action委託。您可以使用匿名委託操作完成您需要的大多數任務。

最後,就像警告一樣,我建議您在專用線程上使用Semaphore或EventWaitHandle,而不是Thread.Sleep。當它不必要時,它肯定比一次又一次地執行你的後臺循環更友好。

+0

謝謝,我打算一遍又一遍地運行後臺循環。我會考慮一個事件等待處理程序 – Raynos 2010-08-13 22:40:20

+1

我同意關於'Thread.Sleep'的警告;然而,操作應該實現'SynchronizationContext'而不是過時的'ISynchronizeInvoke'。 – 2010-08-14 01:21:16

0

對於您創建的線程,只能在創建它們時指定ThreadStart委託。沒有規定將一個不同的委託注入到創建的線程中。線程池的不同之處在於,它允許您將代表提交給代表您開始的以前創建的線程。

目前尚不清楚您嘗試解決什麼問題。你試圖通過在一個線程上運行多個委託來完成(或避免)什麼?