簡體   English   中英

多線程(TThread)Delphi 應用程序不會終止

[英]Multithreaded (TThread) Delphi application will not terminate

我編寫了一個應用程序(使用 Delphi 2009),它允許用戶選擇一系列可以在許多不同系統上運行的查詢。 為了允許查詢並發運行,每個查詢都在自己的線程中運行,使用TADOQuery對象。 這一切正常。

我遇到的問題是當我嘗試在查詢仍在運行時關閉應用程序(因此一個單獨的線程處於活動狀態)。 當我創建每個線程時,我將線程的THandle記錄在一個數組中。 當我嘗試關閉應用程序時,如果任何線程仍在運行,我會檢索線程的句柄並將其傳遞給TerminateThread ,理論上應該終止線程並允許應用程序關閉。 然而,這不會發生。 主窗體的onClose事件被觸發,看起來應用程序正在關閉,但進程仍然處於活動狀態,我的 Delphi 界面看起來好像應用程序仍在運行(即“運行”按鈕變灰,調試視圖處於活動狀態等)。 在我手動結束進程(在 Delphi 中使用 Ctrl-F2 或通過任務管理器)之前,我無法控制回 Delphi。

我使用TerminateThread因為查詢可能需要很長時間才能運行(在我們處理一百萬左右的記錄的情況下需要幾分鍾,這在最終用戶環境中是完全可能的)並且在它運行時,除非我“我錯了,線程將無法檢查Terminated屬性,因此如果在查詢返回之前將其設置為 True,則線程將無法自行結束,因此我無法以通常的方式終止線程(即通過檢查 Terminated 屬性)。 可能的情況是用戶想在運行大查詢時退出應用程序,在這種情況下,我需要應用程序立即結束(即所有正在運行的線程立即終止),而不是強迫它們等待所有查詢都完成完成運行,所以TerminateThread將是理想的,但它實際上並沒有終止線程!

有人可以幫忙嗎? 有誰知道為什么TerminateThread不能正常工作? 任何人都可以提出任何建議讓運行大型 ADO 查詢的線程立即終止嗎?

您應該能夠通過掛鈎 OnFetchProgress 事件並將 Eventstatus 變量設置為 esCancel 來取消 ADO 查詢。 這應該會導致您的查詢終止並允許線程正常關閉,而不必求助於 TerminateThread。

與其將線程與 TADOQuery 一起使用,也許您應該考慮使用 ADO 的異步選項。

ADOQuery1.ExecuteOptions := [eoAsyncExecute, eoAsyncFetch, eoAsyncFetch];

然后當您的應用程序關閉時,您可以調用:

ADOQuery1.cancel;

正如您在使用TerminateThread在 msdn 中所讀到的那樣是危險的。

TerminateThread 是一個危險的函數,只能在最極端的情況下使用。 只有當您確切地知道目標線程正在做什么並且您控制目標線程在終止時可能正在運行的所有代碼時,才應該調用 TerminateThread。

但它在殺死線程方面也非常有效。 你確定你的結論是對的嗎? 也許線程已被殺死,但另一個線程仍在運行? 也許你的句柄不是線程句柄? 你能告訴我們一些代碼嗎? 或者甚至更好:我們可以為自己嘗試一個小的工作示例?

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM