我知道沒有直截了當的答案。
如果你想要寫一個強大的DLL,你應該幾個場景做準備:
- 你的代碼是在.NET應用程序託管,在默認的AppDomain。 (微不足道的場景)
- 您的代碼託管在.NET應用程序中,位於由主機代碼創建的AppDomain中。
- 您的代碼託管在非託管應用程序(託管CLR)中。
第三種情況是最難處理的,因爲CLR可以被其主機禁用,所以託管代碼將不再執行。
System.Windows.Forms.Application.ApplicationExit
是不好的,因爲它只適用於WinForm應用程序。
System.AppDomain.DomainUnload
本身並不好,因爲它從來沒有爲默認AppDomain提出。
AppDomain.ProcessExit
本身並不好:如果您的代碼託管在單獨的AppDomain中,主機可能會卸載該AppDomain,因此事件永遠不會升起。
我試圖覆蓋大多數情況下,使用類似的開始:
if (AppDomain.CurrentDomain.IsDefaultAppDomain())
AppDomain.CurrentDomain.ProcessExit += MyTerminationHandler;
else
AppDomain.CurrentDomain.DomainUnload += MyTerminationHandler;
但做注意到下面的備註(from MSDN):
所有ProcessExit事件的總執行時間處理程序是有限的,就像在過程關閉時所有終結器的總執行時間是有限的。默認值是兩秒。非託管主機可以通過使用OPR_ProcessExit枚舉值調用ICLRPolicyManager :: SetTimeout方法來更改此執行時間。
上述代碼仍然使第三種情況無人看管。 有兩種方法,我知道的與該方案處理(連同前兩個)
首先,你可以使用System.Runtime.CompilerServices.RuntimeHelpers.ExecuteCodeWithGuaranteedCleanup
方法,如下所示:
{
// this goes at your code's entry point
RuntimeHelpers.ExecuteCodeWithGuaranteedCleanup(MyExecutionCode, MyCleanupCode, null);
}
static void MyExecutionCode(object data) { /* your execution code here */}
static void MyCleanupCode(object data, bool exceptionThrown) { /* your cleanup code here */ }
其次,你可以利用System.Runtime.ConstrainedExecution.CriticalFinalizerObject
類(see MSDN here)通過繼承它並將清理代碼放入終結器中。這要求您的清理代碼遵守Constrained Execution Region準則。
您可以嘗試SetConsoleCtrlHandler的CTRL_CLOSE_EVENT事件。 http://msdn.microsoft.com/en-us/library/windows/desktop/ms686016%28v=vs.85%29.aspx – 2013-05-21 15:16:54