2012-03-07 28 views
8

我有一個方法void DoWork(object input)需要大約5秒鐘才能完成。我已經閱讀ThreadThreadPool更適合這些較長的操作,但我遇到了問題。主題:如何在線程完成後重新啓動?

我點擊一個按鈕,它調用threadRun.Start(input)它運行並完成罰款。我再次點擊按鈕,收到以下異常:

Thread is running or terminated; it cannot restart.

你能不能「再利用」主題?我應該使用ThreadPool嗎?與ThreadPool相比,Thread爲什麼「更適合更長時間的操作」?如果你不能重用一個線程,爲什麼要使用它(即它提供了什麼優點)?

+0

我剛剛查了我的一些代碼,每次我重新創建線程我需要重用它。我這樣做是因爲我的代碼中也出現了完全相同的錯誤。在我的情況下,這樣做並不昂貴,所以我沒有進一步調查。 – ChrisF 2012-03-07 22:41:48

+0

對於螺紋VS線程池檢查此[計算器帖] [1] [1]:http://stackoverflow.com/questions/230003/thread-vs-threadpool – 2012-03-07 22:45:51

回答

10

你不能「重用」一個線程嗎?

可以。但是你必須編寫線程不要終止,而是等待更多的工作。這就是線程池的功能。

我應該使用線程池?

如果你想重新使用一個線程,是的。

與ThreadPool相比,Thread爲什麼「更適合長期操作」?

想象一下,服務於大量快速操作的線程池。你不想有太多的線程,因爲電腦一次只能做很多事情。每一個你做線程池的長操作都會連接池中的一個線程。所以池必須有很多額外的線程或可能缺少線程。兩者都不會導致高效的線程池設計。

對於較長的操作,創建和銷燬線程的開銷相比,運行成本非常小。因此,僅僅爲操作使用線程的正常缺點不適用。

如果你不能重用一個線程,爲什麼要使用它(即它提供了什麼優點)?

我假設你的意思是使用專用於作業的線程,然後終止使用線程池。優點是線程數將始終等於這種方式的作業數量。這意味着每次開始工作時都必須創建一個線程,並且每次完成一個線程時都銷燬一個線程,但是您永遠不會有額外的線程,也不會在線程中出現短缺。 (這可能是與我的好事/ O綁定線程,但可以是一件壞事,如果多數線程是CPU密集型的大部分時間。)

+0

很大的反響!感謝您花時間回答我的許多問題。 :) – john 2012-03-08 15:22:35

1

由於消息狀態,您無法重新啓動線程。您可以簡單地爲您的下一個操作創建一個新線程。或者,您可能會考慮設計後臺線程繼續工作,直到完成所有任務,而不是爲每個任務啓動一個新線程。

1

它在設計上看起來像這樣。

我遇到了同樣的問題,我能找到的唯一解決方案是重新創建線程。在我的情況下,我沒有經常重新啓動線程,所以我沒有再看。

一個搜索現在已經變成了this thread on social.msdn那裏接受的答案狀態:

停止或中止線程不能再次陳述。

MSDN重複這個問題,以及:

試圖通過調用已終止線程啓動以重新啓動中止的線程拋出一個ThreadStateException

0

它只是在後臺模式。聽起來你需要使用ThreadPool,因爲重新啓動和重新創建Thread對象是非常昂貴的操作。如果您有一個長時間運行的作業可能會持續比您的主進程更長的時間,那麼請考慮使用Windows服務。

1

for(;;){}while(true){}是「重用」線程的有用構造。通常,線程在這些循環頂部的某個同步對象上等待。在你的例子中,你可以等待一個事件或信號量並從你的按鈕OnClick()處理程序發出信號。

3

Thread.Start文件說:

一旦線程終止,它不能與其他呼叫 重新啓動。

線程不可重複使用。前一段時間我已經遇到了這個問題,解決方案是在需要時創建一個新的Thread實例。

相關問題