首先,让我们读一下MSDN中的CriticalFinalizerObject,我们可以读到:
在从 CriticalFinalizerObject 类派生的类中,公共语言运行时 (CLR) 保证所有关键的终结代码都将有机会执行,前提是终结器遵循 CER 的规则,即使在 CLR 强制卸载应用程序域的情况下也是如此或中止线程。
这里的主要词是UNLOAD。
其次,让我们再次阅读MSDN,这次是关于托管线程中的异常:
如果这些异常在主线程中或在从非托管代码进入运行时的线程中未处理,它们将正常进行,从而导致应用程序终止。
主要词是TERMINATION。
因此,当主线程中存在未处理的异常时 - 应用程序终止,但 CriticalFinalizerObject 仅有助于卸载域。
例如,CriticalFinalizerObject 可以在这种情况下提供帮助:
// Create an Application Domain:
AppDomain newDomain = AppDomain.CreateDomain("NewApplicationDomain");
// Load and execute an assembly:
newDomain.ExecuteAssembly(@"YouNetApp.exe");
//Unload of loaded domain
AppDomain.Unload(newDomain);
在这种情况下,域被卸载,CriticalFinalizerObject 向您保证,您的终结器将被调用。
在您终止应用程序的情况下,您可以尝试订阅
AppDomain.CurrentDomain.UnhandledException
并手动完成您的对象。
UPD:
Jeffrey Richter 在他的“通过 C# 的 CLR”一书中写了关于 CriticalFinalizerObject 的文章,它适用于将代码发送到 SQLServer 的情况,例如可以将 C# 作为过程运行。在这种情况下,如果 SQLServer 将卸载库的域,CriticalFinalizerObject 可以帮助您清理对象。此外,CriticalFinalizerObject 适用于您需要在对象的终结器中调用另一个对象的方法的情况,因为 CriticalFinalizerObject 向您保证,它将在所有非 CriticalFinalizerObject 对象的终结器之后调用它的终结器。