2010-03-19 82 views
3

即使我的C#應用​​程序崩潰(刪除臨時文件等),我也希望在執行結束時執行一些清理代碼。在C#中可以做到嗎?在應用程序崩潰時執行代碼

謝謝!

+1

「崩潰」是什麼意思? – wtaniguchi 2010-03-19 22:59:18

+0

這就是非軟件工程師所說的話:導致應用程序關閉的任何事件(任何線程中未處理的異常,除以0,訪問衝突,來自我的工作者DLL的C++ SEH等等)。 – Warpin 2010-03-19 23:08:12

回答

0

這取決於你的意思是「崩潰」。如果你的意思是一個未處理的異常,你可以爲Application.ThreadException創建一個處理程序。如果崩潰是在託管代碼之外引起的,那麼您就無能爲力。

+0

我希望得到的是某種可重寫的「Terminate」函數,我可以編寫這個函數,這個函數被調用了未處理的異常,訪問衝突或其他任何可以取消我的應用程序。大部分工作都是由C++ DLL完成的,所以處理異常也很好。 – Warpin 2010-03-19 23:06:10

-3

這就是try {} finally {}的用途。將所有的代碼包裹在你的main方法中,應該這樣做。

+4

在簡單場景中,這可能已經足夠好了,但多線程應用程序又如何呢? – 2010-03-19 23:16:05

8

這取決於你的意思是「崩潰」。

如果您想要處理任何會導致應用程序無法處理的未處理異常,則可以將事件處理程序附加到AppDomain.UnhandledException事件,然後處理事件處理程序中的任何錯誤。

此外,在.Net 4.0中有一個AppDomain.FirstChanceException,在發生異常時執行任何catch塊之前調用。

但是,可能會發生真正的崩潰(例如從終結器拋出的異常),導致無法輕易處理的致命應用程序退出,但在大多數情況下,AppDomain.UnhandledException事件可能就足夠了。

+0

我想在任何崩潰之前調用方法。 AppDomain.FirstChanceException幫助了我。謝謝! – 2018-01-18 08:21:20

2

有幾個事件可以通過訂閱來獲得異常通知。

另外,正如其他人所提到的,圍繞單個入口點的finally塊將在主線程中遇到任何異常。

[我不建議嘗試從這些處理程序中恢復您的應用程序。特別是在AppDomain.UnhandledException事件的情況下,你的應用程序已經出來了,你應該讓它關閉。只使用這些處理程序進行最後一分鐘的清理或日誌記錄。]

5

如果您的應用程序崩潰,那麼嘗試執行清理代碼並不安全,您不知道什麼已損壞,直到您的應用程序實際退出,文件可能被鎖定等。

所以我建議你把這個清理代碼放在應用程序啓動。讓您的應用程序在啓動之前查找臨時文件等,然後才能創建正常的臨時文件(如果它找到它們),那麼它可以刪除它們或嘗試修復/重新使用它們。

爲了實現這一點,您可以讓應用程序寫入一個臨時文件的日誌,它創建並刪除該日誌文件,當它關閉成功。這樣,當你在啓動時發現日誌文件時,你知道最後一次運行是崩潰,並且你必須進行清理。

當然,如果允許應用程序的多個實例同時運行,這會變得更加複雜,但同樣適用於在崩潰時進行清理。

1

如果您的應用程序清理至關重要,則可以創建一個監視器應用程序,該應用程序將是用戶實際啓動的應用程序。它會啓動你的主應用程序,然後監視它的進程句柄。如果你的主應用程序崩潰,它的進程句柄將發出信號,你的顯示器應用程序可以清理,甚至如果你願意重新啓動主應用程序。我通常將它與一個已命名的互斥鎖結合使用,該互斥鎖用於向監視器應用程序發回主應用程序希望關閉的信號,以便它不會重新啓動它。

相關問題