[Delphi]如何判斷線程已執行完畢?

來源:互聯網
上載者:User

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;

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.