2011-06-13 87 views
2

一次,在測試過程中,我的C++ Builder/Delphi應用程序在後臺工作線程中引發了未捕獲的異常。如我所料,EurekaLog發現了異常併發送了錯誤報告,並且一切似乎都正常。但是,當我關閉應用程序的主窗口時,由於應用程序仍然在任務管理器中列出(並且仍然有資源打開),所以仍在後臺運行一些內容。什麼可能導致C++ Builder/Delphi線程和應用程序無法關閉?

我試圖重複這個問題,故意在後臺工作線程中引入各種錯誤,但我不能。

什麼會導致線程和應用程序繼續像這樣運行,即使主窗口已關閉(並且大概已調用PostQuitMessage)?

我該如何確保應用程序始終乾淨地關閉?

+0

你有沒有可以無限阻止的EnterCriticalSection代碼?這是一個非常常見的死機,在關機時就能正常工作。 – 2011-06-13 18:19:36

回答

7

第一條規則是線程主要執行程序方法應該被寫入,以便它們可以正常發送並關閉,第二條規則是不應該只關閉應用程序的主線程,然後希望其他線程在自己的時間內關閉,爲了安全起見,您應該指示所有後臺線程停止,等待關閉完成,然後關閉主線程。一個最小的螺紋例如:

procedure TMyThread.Execute; 
begin 
    Init; 
    while not Terminated do 
     OneWorkItem; // inside OneWorkItem, you ALSO need to check for Terminated 
end; 

一個最小的主要形式/主線程例如:

procedure TMyMainForm.CheckAndShutdown; 
    begin 
    if FPendingShutdownFlag then 
     if AllBackgroundThreadsTerminated then 
      Self.Close; 
    end; 

您可以設置FPendingShutdownFlag並具備上述功能從應用程序空閒處理循環中調用。當用戶單擊主窗體FormClose時,如果AllBackgroundThreadsT​​erminated返回false,請將CanClose設置爲false,然後設置FPendingShutdownFlag := true

如果你製作了一個無限循環(雖然是true),應用程序並沒有乾淨地關閉,即使它看起來像你。不知何故,應用程序被終止,並且正在運行的線程可能會突然消失,或者它們可能會死鎖或以其他方式失敗,因爲它們可能正在使用線程2中的資源,並且正忙於在線程1中釋放。

您可能有一個或多個故意爭用條件,因爲您可能沒有將您的線程執行方法寫成可中斷的,或者您可以在確定後臺線程已經啓動之前開始關閉主應用程序線程和VCL及其對象完全關閉。

+0

我一定不能很好地解釋自己。我盡我所能寫我的線程是可以中斷的,檢查TThread.Terminated,以避免死鎖和資源問題等。不知怎的,一次,儘管如此,我的應用程序沒有終止;它仍然在後臺運行,即使它的形式已經關閉。我想知道爲什麼以及如何預防它。我盡我所能想到的複製錯誤狀態(包括添加無盡的while(true)循環),以便我找出如何從中恢復,但我仍然無法複製錯誤狀態。 – 2011-06-13 15:27:38

+0

然後,它聽起來像你正在尋找一個難以捉摸的競爭條件或其他類似的間歇性異步失敗在你的代碼。您是否有任何可能長時間阻止的TThread.Synchronize調用?你有睡眠()電話嗎?例如,你可能會有我稱之爲「睡美人」的問題。後臺線程在關閉主線程之前必須完全關閉,後臺線程完全使用ANY對象或者主線程將釋放。 – 2011-06-13 15:39:44

+0

在我看來,你應該先用大量的outputdebugstring消息來測試代碼,然後在代碼失敗的客戶端系統上運行它,以及MS DebugView(一個outputdebugstring查看器)並查看代碼的哪些部分在客戶端系統上達到或未達到。 – 2011-06-13 18:18:37

1

你確定工作線程終止,並且主線程沒有等待它完成嗎?

+0

我不確定發生了什麼,我只看到過這個問題,但我想確保它不會在客戶機器上重現。如果我故意讓工作線程永不終止(通過在C++中添加一個「while(true);」循環),應用程序仍然完全關閉,所以我認爲問題不在於主線程正在等待工人終止。 – 2011-06-13 14:10:52

+0

等一下。您添加了一個確保線程永不終止的while循環。但在其他地方可以打電話給TThread.Terminate。所以你所做的是使它不太可能會關閉乾淨。難怪你的應用程序壞了。 – 2011-06-13 15:10:51

+0

@Warren P:我想你可能誤解了。看到我對你的答案的評論。 – 2011-06-13 15:28:58

相關問題