2010-09-03 76 views
1

我正在使用Delphi(7-2010)並試圖找出處理異常並釋放應用程序形式的好方法。該應用程序有幾個由Application對象擁有的表單。當用戶註銷時,我需要釋放所有現有表單,以便不保留用戶狀態,然後顯示登錄對話框以供登錄的下一個用戶使用。德爾福:當一個表單在註銷應用程序時無法釋放時該怎麼辦

偶爾,嘗試釋放其中一個表格。這會將表單留在內存中,但處於未知/不可用狀態,因此我無法重新使用下一個用戶的表單,而且我也無法從內存中清除它。由於表單由應用程序擁有,我無法直接爲下一個用戶創建表單的新版本,因爲它會導致VCL中出現「名爲MyForm的組件已存在」錯誤,而且我有點厭惡無論如何在內存中都有舊的表單實例。

我想看看別人會在這種情況下做什麼。這裏有一些想法:

  • 終止應用程序,當你得到這些例外,所以你一定要擦拭石板乾淨。用戶無論如何都會註銷,所以他們很可能會在應用程序中完成。根據需要選擇重新啓動應用
  • 使表單不屬於應用程序,因此您可以創建它們的多個實例,並確保至少隱藏任何不可釋放/損壞的表單。
  • 動態生成每個表單的名稱,或將其設置爲空白,這樣就不會有重複的名稱,並且VCL中沒有「已存在」錯誤。
  • 編寫一個應用程序時非常好,在釋放對象時不會出現異常(不切實際 - 我需要針對意外錯誤的應急計劃)。


我的解決方案是上面的最初想法之一。我在循環中添加了一個try/except塊來釋放窗體,如果有異常,我會向用戶顯示錯誤消息而不提高它,然後調用ExitProcess(0)立即終止應用程序。

回答

6

真的沒有好方法來處理從析構函數中引發的異常。我不會稱它爲「不現實的」,期望它們永遠不會被提出,因爲析構函數不應該做任何可能導致異常的事情。如果你除了釋放內存或其他清理(釋放句柄,關閉連接等)之外的任何事情,你幾乎肯定會做錯事情。

什麼導致例外,BTW?你能否一致地重現錯誤?你的最佳行動是糾正錯誤。不應該有太多。

+0

這些錯誤代表許多事情。過去的例子是試圖保存其狀態並因任何原因失敗的第三方組件,例外情況下斷開連接/數據集,未知原因的AV等。這並不是說這些錯誤是衆多或常見的,但我想成爲積極主動並使應用程序能夠智能地行動,即使在出現新的/意外錯誤的罕見情況下也是如此。 – Anagoge 2010-09-03 22:28:49

+1

@Anagoge:好的。那麼,如果用戶在任何時候註銷,那麼我會在轉儲異常日誌並將其發送給您之後終止該應用程序。 (如果您沒有辦法做到這一點,請查看MadExcept或EurekaLog。它們對於跟蹤部署代碼中的錯誤非常重要,這是實際讓調試器連接到用戶應用程序的下一個最好的事情。) – 2010-09-03 23:06:51

4

大多數情況下,當銷燬表單時發生錯誤,因爲仍然有一些事件處理程序正在執行並引用已經銷燬的對象。
這就是爲什麼TForm.Release已被創建用於代替TForm.Free在這種情況下。

來自幫助:
使用發佈銷燬表單並釋放其關聯的內存。 在窗體上的組件的窗體和事件處理程序的所有事件處理程序都已完成執行之前,發佈不會破壞窗體。發佈還可以確保表單的事件隊列中的所有消息都在表單發佈之前得到處理。表單或其子項的任何事件處理程序應該使用Release而不是Free(Delphi)或刪除(C++)。如果不這樣做可能會導致內存訪問錯誤。

相關問題