2014-01-17 37 views
7

我正在使用TThread,我只需要找出線程是否仍在運行並終止應用程序,如果需要很長時間。德爾福檢查TThread是否仍在運行

例:

MyThread := TMyThread.Create; 
MyThread .Resume; 
MyThread.Terminate; 

total := 0; 
while MyThread.isRunning = true do // < i need something like this 
begin 
    // show message to user to wait a little longer we are still doing stuff 
    sleep(1000); 
    total := total + 1000; 
    if total > 60000 then 
    exit; 
    end; 

這可能與德爾福?

回答

7

對您的問題的直接回答是TThreadFinished財產。但是,我不建議這樣做。它會將您引導至您在該問題中出現的基於相當討厭Sleep的循環。

有一些清潔的選擇,至少包括以下內容:

  1. 使用WaitFor阻塞,直到該線程完成。這將阻止調用線程,這將阻止顯示UI或響應用戶。
  2. 在循環中使用MsgWaitForMultipleObjects,傳遞線程句柄。這允許您等待線程完成,但也爲UI服務。
  3. OnTerminate事件實施事件處理程序。這可以讓你以事件驅動的方式告知線程的消亡。

我建議您使用這些選項中的一個,而不是基於您自己生成的基於Sleep的循環。根據我的經驗,選項3通常會導致最乾淨的代碼。但在不知道所有要求的情況下很難提供嚴格的建議。只有你有這種知識。

+0

不在運行,太難過了。 WaitFor塊,這樣就會破壞線程的目的。我正在避免MsgWaitForMultipleObjects,因爲它很容易在COM應用程序中引起意外的問題。所以我想我與OnTerminate卡住是遠遠不夠好,因爲將不得不添加很多代碼只是爲了檢查是否所有的線程都完成了。 – uacaman

+0

查看我的更新。有'TThread.Finished'。我敦促你不要這樣做,但它確實存在。 –

+0

我沒有TThread.Finished,只是發現OnTerminate沒用。文檔在http://docwiki.embarcadero.com/Libraries/XE2/en/System.Classes.TThread.OnTerminate說OnTerminate調用後執行和之前銷燬,這是不正確的當你試圖釋放線程時調用OnTerminate,但Thread.Free調用WaitFor阻止你的主線程。此行爲阻止使用OnTerminate設置標誌來指示線程的終止,因爲它將阻塞直到完成進程。 – uacaman