所以我創建了一個類:TWorkerThread = class(TThread). 在TWorkerThread我設定的建構式中FreeOnTerminate := True。
然后Worker我在我的TForm. 當我實體化TWorkerThreadforWorker時,我總是使用CreateSuspended := False.
一旦啟動,我需要與執行緒進行的唯一互動是取消行程 ( Terminate) 并檢查行程是否結束(該檢查是基于用戶事件的)。
要檢查執行緒是否仍處于活動狀態,我會:
if (Self.Worker <> nil) and (not Self.Worker.Finished) then
//Still active
這似乎作業正常,但我擔心在某個時候TWorkerThread會<> nil但仍然會.free(記住,TWorkerThread都是FreeOnTerminate := True)。當TWorkerThread“自我毀滅”一旦終止時,它們總是會變成nil嗎?如果沒有,我該如何處理(以避免訪問沖突)?
另一件事,如果 aWorker在它的表單銷毀上處于活動狀態,我會這樣做:
if (Self.Worker <> nil) and (not Self.Worker.Finished) then
begin
Self.Worker.Terminate;
//wait here for completion
end;
Terminate如果我做了之后,WaitFor我會遇到訪問沖突(因為自毀)。我應該在這里強制等待嗎?最好的方法是什么?
這是我在 Delphi 中第一次正確使用 TThread。上面的代碼是我為清楚起見所做的簡化版本。
uj5u.com熱心網友回復:
Delphi中檢查FreeOnTerminate = True的非暫停創建的TThread是否仍在執行的正確方法是什么?
空無一人。
一旦啟動自毀執行緒,您就不再被允許從外部代碼中觸摸持有此類執行緒的參考,因為該參考隨時可能變得陳舊。
在某些情況下(如果您的自定義執行緒類中未修改邏輯處理OnTerminate呼叫),您可以安全地從事件處理程式訪問執行緒參考。但是,這不會幫助您解決問題,因為您不能等待自毀執行緒。在 Windows 上,此類代碼會導致可以捕獲和處理的例外,但在其他平臺上,它會導致未定義的行為和隨機死鎖。但即使在 Windows 上撰寫這樣的代碼也是不可取的。DoTerminateOnTerminate
如果您需要檢查執行緒的狀態,取消它或等待它,您不能使用自毀執行緒。時期。(對于那些可能反對先前陳述的人,是的,在某些情況下,其中一些事情是可能的,但它們通常會導致自己的腳被射中)。
您可以使用以下作業流程TWorkerThread,前提是您保留FreeOnTerminate在False執行緒建構式中并構造未掛起的執行緒。必須從主執行緒呼叫以下所有方法,以避免Worker參考競爭條件。在您的表單打開時擁有一個不執行任何操作的額外執行緒不會給您帶來任何麻煩。
procedure TMyForm.StartWorker;
begin
FreeAndNil(Worker); // or if Assigned(Worker) then Exit;
Worker := TWorkerThread.Create;
end;
procedure TMyForm.CancelWorker;
begin
// this will initiate thread termination and waiting
FreeAndNil(Worker);
end;
procedure TMyForm.Destroy;
begin
// technically we could only use Free here,
// but since other code requires niling the reference this is more consistent
FreeAndNil(Worker);
inherited;
end;
轉載請註明出處,本文鏈接:https://www.uj5u.com/yidong/424523.html
標籤:多线程 德尔福 delphi-10.4-悉尼
上一篇:記錄型別的讀寫屬性
