Delphi線程的終止


  當線程對象的Execute()執行完畢,我們就認為此線程終止了。這時候,它會調用Delphi的一個標准例程EndThread(),這個例程再調用API函數ExitThread()。由ExitThread()來清除線程所占用的棧。

  當結束使用TThread對象時,應該確保已經把這個Delphi對象從內存中清除了。這才能確保所有內存占有都釋放掉。盡管在進程終止時會自動清除所有的線程對象,但是及時清除已經不再使用的對象,可以使內存的使用效率提高。利用將FreeOnTerminate的屬性設置為True的方法來及時清除線程對象時最方便的方法,這只需要在Execute()退出之前設置就行了。設置的方法如下

procedure TTestThread.Execute;
var
    i: Integer;
begin
    FreeOnTerminate:= True;
    for i:=1 to 2000000 do
        inc(Answer, Round(Abs(Sin(Sqrt(i)))));
end;

  這樣,當一個線程終止的時候,就會觸發OnTerminate事件,就會有機會在事件處理過程中清除線程對象了。

  提示:OnTerminate事件是在主線程的環境中發生的。這就意味着,在處理這個事件的過程中,你可以不需要借助於Synchronize()而自由地訪問VCL

 

  要記住Execute()需要經常地檢查Terminated屬性的值,來確認是否要提前退出。盡管這將意味着當使用線程工作的時候,你必須關心更多的事情,但它能確保在線程結束時,能夠完成必要的清除。下面是一段在Execute()增加處理操作的簡單代碼:

procedure TTestThread.Execute;
var
    i: Integer;
begin
    FreeOnTerminate:= True;
    for i:= 1 to 2000000 do 
    begin
        if Terminated then
            break;
        inc(Answer, Round(Abs(Sin(Sqrt(i)))));
    end;
end;

  注意,在某些緊急情況下,你可以使用Win32 API函數 TerminateThread()來終止一個線程。但是,除非沒有別的辦法了,否則不要使用它。例如,當線程代碼陷入死循環中。TerminateThread()的聲明如下

function TerminateThread(hThread: THandle; dwExitCode: DWORD);

  TThread的Handle屬性可以作為第一個參數,因此,TerminateThread()常這樣調用

TerminateThread(MyHosedThread.Handle, 0);

  如果選擇這個函數,應該考慮到它的負面影響。首先,此函數在Windows NT與在Windows95/98下並不相同。在Windows95/98下,這個函數能夠自動清除線程所占用的棧;而在Windows NT下,在進程被終止前棧仍被保留。其次,無論線程代碼中是否有try...finally塊,這個函數都會使線程立即終止執行。這意味着,被線程打開的文件沒有被關閉、由線程申請的內存也沒有被釋放等情況。而且,這個函數在終止線程的時候也不通知DLL,當DLL關閉的時候,這也容易出現enti問題


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM