2011-08-09 77 views
9

有沒有什麼辦法可以抽象出某個特定委託可能執行的線程,以便我可以在調用線程上最初執行它,但是如果執行結果花費的時間超過了一定的時間?是否可以將代理的執行從一個線程移動到另一個線程執行中?

假定代理寫入異步。我沒有試圖採用同步塊並將它們移動到後臺線程來增加並行性,但是我正在尋求通過避免簡單操作的線程開銷來提高異步執行的性能。

基本上我想知道是否有任何方式的委託或lambda的執行可以暫停,移動到另一個線程和恢復,如果我能確定明確的界限棧等

我懷疑這是可能的, 我只是好奇。

回答

3

這是可能的,但它會是尷尬和難以得到正確的。做到這一點的最好方法是使用coroutines。目前符合協程範式的.NET中唯一的機制是C#的迭代器,通過關鍵字yield return。你可能理論上一起攻擊的東西,允許執行方法從一個線程轉換到另一個。然而,這只不過是一個值得攻擊的博客,但我認爲這是可能的。

下一個最佳選擇是繼續並升級到Async CTP。這是C#中提供的一項功能,可以讓您按照您的要求進行操作。建議的await關鍵字和一些聰明的漏洞也將包括在內,這是完美的。最終結果看起來像下面這樣。

public async void SomeMethod() 
{ 
    // Do stuff on the calling thread. 

    await ThreadPool.SwitchTo(); // Switch to the ThreadPool. 

    // Do stuff on a ThreadPool thread now! 

    await MyForm.Dispatcher.SwitchTo(); // Switch to the UI thread. 

    // Do stuff on the UI thread now! 
} 

這只是許多惡人很酷的技巧,你可以用新的await關鍵字做之一。


實際上你可以注入的代碼的執行到一個現有的線程的唯一方法是,如果目標是專門爲接受一個工作項目的形式注入。

你可以看到我的回答here一個這樣的嘗試在模仿await關鍵字迭代器。 MindTouch Dream框架是另一種可能更好的變體。關鍵是應該可以通過一些巧妙的黑客攻擊來切換線程。

+0

迷人!我一定會對'await'和Async CTP做更多的研究。我承認,當我一讀回來的時候,我並沒有完全理解「等待」的內容。 Wow; – devios1

+0

哇;這是光滑的。 –

2

不容易。

如果將您的委託構造爲狀態機,則可以跟蹤狀態之間的執行時間,並在達到所需閾值時,在新線程中啓動下一個狀態。

一個更簡單的解決方案是在一個新的線程中啓動它,以開始。任何不可接受的理由?

(從我的手機發布 - 我會提供一些僞代碼,當我在一個真正的鍵盤如果需要的話)

+0

嗯,這是一個有趣的想法,我沒有考慮。出於我的目的,我更感興趣的是保持代表的格式非常簡單(狀態機將會過度)。我可能會最終走上使用線程池線程的路線;我只是好奇,如果有什麼辦法可以優化那些微不足道的操作。 – devios1

+0

是的,你只是說,在一個循環中做一堆相同的操作,FSM是矯枉過正的。但是,在這種情況下,您可以根據估計的工作負載/迭代情況估計所需的執行時間,並預先決定使用哪個線程。 –

+0

是的,我也已經做了一些思考......也許保留過去執行時間的數據庫,並使用平均值做出關於它是否應該在後臺線程上運行的明智決定。當然,你必須考慮做所有的指標可能需要的時間比通過在當前線程上運行得到的優化時間要長(事實上,它幾乎可以保證)。所以真的成爲一個有爭議的問題。儘管如此,仍然有趣的想法。 – devios1

1

不,我不認爲這是可能的。至少不直接與常規代表。如果你創建了一些IEnumerable,在一些工作之後產生,那麼你可以手動運行它的一些迭代,然後在經過這麼多次迭代之後切換到在後臺線程上運行它。

ThreadPool和TPL的任務應該有足夠的性能,只需總是在後臺線程上運行它。除非你有一個特定的基準測試,表明使用任務會產生一堆開銷,這聽起來像是在試圖過早地進行優化。

+0

事實上,你是對的過早優化,我很清楚它(我承認有一個過早的優化問題,哈哈)。因此,正如我所說的,爲什麼我沒有認真對待它,更多的是出於對未來潛在改善的好奇心。 ;) – devios1

相關問題