MyThread:=TMyThread.Create(False);
如何判斷線程MyThread已執行完畢?
因為程式中有個事件必須等某線程完成後才執行
說明中說可以用ReturnValue,但我感覺這個值一直是0,沒有變化啊
----------------------
用MyThread.Waitfor或者WaitForSingleObject(MyThread.Handle, INFINITE)
----------------------
把你要執行的事件放到線程的Excute中
MyThread.Execute
....
FreeOnTerminate:=True;
Onterminate:=你要執行的事件;
----------------------
type
TMyThread = class(TThread)
protected
procedure Execute; override;
end;
{ TMyThread }
procedure TMyThread.Execute;
begin
FreeOnTerminate := False;
Sleep(5000);
end;
procedure TForm3.Button1Click(Sender: TObject);
var
T : TMyThread;
begin
T := TMyThread.Create(False);
try
T.WaitFor;
ShowMessage('執行完了');
finally
T.Free;
end;
end;
procedure TForm3.Button2Click(Sender: TObject);
var
T : TMyThread;
begin
T := TMyThread.Create(False);
try
if WaitForSingleObject(T.Handle, INFINITE) = WAIT_OBJECT_0 then
begin
ShowMessage('執行完了');
end;
finally
T.Free;
end;
end;
//方法是可以的,但是有一個缺點,當執行線程的時候主程式也會停下來等待線程的結束,主程式會暫
停響應,這樣調用多線程就沒有意義了。
----------------------
用Onterminate事件當然可以,但是這時線程並沒有結束,僅僅表示Execute方法調用
結束了,而用WaitforSingleObject就不同了
----------------------
使用Onterminate事件固然有它的局限性,因為觸發Onterminate事件的時候線程還沒有完全結束,用它的優點是線程執行的同時,主程式也可以繼續執行,這也是多線程的優點之一。
要實現線程完全結束才觸發主程式繼續執行的話,主線程中執行WaitFor是比較好的實現方法,然而主線程調用WaitFor必須用MsgWaitForMultipleObjects來等待線程,而不是WaitforSingleObject。因為線上程函數Execute中可能調用Synchronize處理同步方法,而同步方法是在主線程中執行的,如果用WaitForSingleObject等待的話,則主線程在這裡被掛起,同步方法無法執行,導致線程也被掛起,於是發生死結。
如果必須要用WaitForSingleObject,應該另開線程來調用WaitForSingleObject,而不是在主線程。
以上是在下愚見,見笑了!哈!
----------------------
這樣可以使得介面不"死",但是由於ProcessMessages的緣故,不能保證某段代碼不被執行,除非設定一個標誌..
procedure TForm1.Button3Click(Sender: TObject);
var
T: TMyThread;
H: THandle;
W: DWord;
begin
T := TMyThread.Create(False);
H := T.Handle;
repeat
W := MsgWaitForMultipleObjects(1, H, False, INFINITE, QS_ALLINPUT);
Application.ProcessMessages;
until (W = WAIT_OBJECT_0) or (W = WAIT_FAILED);
ShowMessage('執行完了');
T.Free;
end;
----------------------
//等待一個線程結束的關鍵代碼。絕對可行
var
i:dword;
isquit:boolean;
begin
if assigned(AThread) then
begin
isquit:=GetExitCodeThread(AThread.handle,i);
if isquit then
begin
if i=STILL_ACTIVE then
begin
WaitForSingleObject(AThread.Handle,INFINITE
);
end
end;
end;
end;