2008-12-24 21 views
11

或者是沒關係做這樣的事情:應該總是保持對C#中正在運行的線程對象的引用嗎?

new Thread(new ThreadStart(delegate { DoSomething(); })).Start(); 

我似乎記得,在這種情況下,Thread對象將被垃圾收集,但底層的OS線程將繼續運行,直到委託的末尾傳入它爲止。我基本上尋找ThreadPool功能,但不希望線程成爲後臺線程(即我希望他們保持應用程序活着)。

更新:據Jason介紹,CLR實際上在運行時保持對Thread對象的內部引用,所以在線程退出之前它不會被垃圾回收。

+1

想一想這個問題的一種方法:「如果對象不存在,孤立線程中的執行邏輯如何能夠調用System.Threading.Thread.CurrentThread?」 – 2008-12-24 14:23:08

+0

傑森,你假設有人會想到首先嚐試這個來測試這個。 ...我的意思是,我當然會......呃......呃...... =( – 2017-06-13 20:42:55

回答

11

我一般發現,如果我需要直接啓動一個新的線程,你是在你的例子中,而不是從線程中抓取一個池,那麼它是一個長時間運行的線程,稍後我需要一個引用來終止它,監視它等等。對於像後臺線程調用IO這樣的短線程,我總是使用線程池線程(通常間接通過someDelete.BeginBlah(...)方法調用)。當使用像這樣的線程池線程時,我更喜歡不保留引用。我不知道另一位程序員是否可能不適當地使用該線程的引用。如果我不需要參考,我不會把它放在雜亂的代碼中。

編輯:要回答關於正在垃圾收集的線程的編輯,這不會在線程運行時發生。 CLR保持對每個正在運行的線程的引用。表示線程的對象不會被收集。

2

這取決於。在用戶可以取消線程操作的情況下,應該保留引用,以便在用戶需要時可以取消線程。在其他情況下,可能不需要存儲參考。

+0

取消是不必要的 - 這是一個背景(同步)操作,但我希望它在關機時保持應用程序活着它可以在退出之前執行最後的同步。我使用ThreadPool直到我意識到退出應用程序中止了線程。 – devios1 2008-12-24 04:47:25

0

問這個問題「這個線程多久可以啓動?」可能會很好。它是每個應用程序,每個類,每個對象實例還是每個方法的調用?這可能會告訴你什麼樣的變量(如果有)來存儲它。

+0

基本上我會按照每個〜5分鐘的時間表執行該行,並擔心它是否會泄漏,或線程是否正常運行 – devios1 2008-12-24 05:00:11

0

是的,你應該,因爲你永遠不知道什麼時候你將不得不改變代碼以便以某種方式處理線程。那樣的話,把太多東西放在這樣一條線上就太難看了。

說實話,你可以按自己的方式去做,所以答案真的歸結爲代碼風格偏好。

0

除了上面發佈的「m3rLinEz」之外,還有一個缺點是如果線程發生異常,甚至很難檢測到這種情況。

1

我已經在生產代碼中執行此操作的情況很多。所以,是的定義並在一行中啓動一個線程而不保留一個引用是它的地方。我想保留一個參考「以防萬一」你以後重新設計,需要它是沒有創建最簡單的作品的原則。

而且,對於第二部分,不會在運行時不會GC'd;線程是GCtor從中追溯引用的根級對象。線程實例一旦被任何正在運行的線程(包括啓動的線程)無法訪問,它就只會被GCd訪問。

並注意泄漏創建但從未啓動的線程實例。我相信他們會永遠活着。

相關問題