2010-09-24 113 views
5

你好 在我的表單中,我在運行時創建TFrame。在這個框架下,我用無限循環中的執行命令創建後臺線程。但是當我摧毀這個框架時,我應該銷燬這個線程。 我試試正確的線程銷燬

thread.Suspend; 
thread.Terminate; 
FreeAndNil(thread); 

但得到AV和ThreadError。 我應該如何銷燬線程?

+0

可能重複(http://stackoverflow.com/questions/3557105/free-a-tthread-either-automatically-or-manually) – 2010-09-24 15:50:04

+3

不要暫停線程。 terminate方法只是將Terminated屬性設置爲true,並且Execute方法負責終止線程。如果它被暫停,它將不會有機會終止。 – jachguate 2010-09-24 23:26:54

+0

上面的代碼的另一個問題是,它可能會在線程發生更改以終止正常方式之前釋放該線程。 – 2010-09-25 12:19:15

回答

13

您必須確保線程退出它的執行方法才能正確終止它。

代碼可能是這樣的:

procedure TThread.Execute; 
begin 
    while not Self.Terminated do 
    begin 
    //do something 
    end; 
end; 

調用此當你想摧毀線程:

thread.Terminate; 
thread.WaitFor; 
FreeAndNil(thread); 
+0

沒有必要從外部調用Terminate和WaitFor,因爲線程析構函數會自行完成。儘管在釋放任何字段之前,可能需要從覆蓋的析構函數調用它,以確保這些內容不再在線程中使用。 – mghie 2010-09-25 13:51:12

4

這是足以做thread.Terminate。但是你可能想在創建時設置thread.FreeOnTerminate := true

當然,在線程的緊密循環中(即在Execute中),您需要檢查線程是否被請求終止(檢查Terminated屬性)。如果您發現線程已被請求終止,只需從循環中斷開並退出Execute

+0

thread.Terminate僅將FTerminated屬性設置爲True。它不會破壞線程。 – Linas 2010-09-24 16:01:14

+2

我知道。但是每個線程都必須在其Execute方法中檢查它。我假設OP正在這樣做。 – 2010-09-24 16:03:33

4

你不應該調用一個的TThread它不是安全的這樣做,並恢復暫停應該只用於啓動被創建暫停的線程。

在德爾福2010年的暫停和恢復,貶低和方法啓動被引入來加強這一點。

如需更完整的解釋,請在Codegears論壇中查看此thread

說了有兩種方法我會終止並釋放tthread。

1:我設置FreeOnTerminate當線程被創建,所以我只是打電話。

Thread.Terminate; 

2:顯式釋放線程,因爲我需要在釋放線程並終止之後讀取公共屬性的結果。

Thread.Terminate; 
Thread.WaitFor; 
//Do somthing like read a public property from thread object 
if Thread <> nil then FreeAndNil(Thread); 

在主執行循環它可能是一個好主意,投入。 一些異常處理或者你可能想知道爲什麼會出現線程終止其自身。如果線程設置爲FreeOnTerminate,並且在嘗試釋放它時它已經釋放,這可能會導致AV。的[自動或手動釋放一個的TThread]

procedure TThread.Execute; 
begin 
    while not Terminated do 
    begin 
    try 
     //do something 
    except 
     on E:Exception do 
     //handle the exception 
    end; 
    end; 
end;