请看这篇博文:AppDomain.ProcessExit is notGuaranteed to be called。从帖子中引用:
不保证调用 AppDomain.ProcessExit。它非常有弹性,可以处理低信任 IL 可能导致的常见问题(异常、内存不足等),但有些事情(如粗鲁的进程关闭),进程内事件永远无法抵御.
(...)
回调是从进程内部调用的。如果进程粗鲁地退出,回调将不会被调用。粗鲁退出的常见来源包括:
- 通过 TaskManager 或 kernel32!TerminateProcess 从外部杀死。
- Stackoverflow 处理程序消耗超过保护页面。
ProcessExit 事件就像告诉某人“请给我打电话说你快死了”。如果死亡来得足够快,他们可能无法传达信息。
事实上,我已经尝试过您的代码,并且在取消注释第 1 行甚至第 2 行时它不会打印“proc exit” !(我尝试在 Visual Studio 2013 中针对所有 .NET 版本进行编译)。当然,当没有抛出异常并且进程正常退出时,它会打印它。(编辑:如果我在发布模式下编译代码,我会看到“proc exit”消息,但在调试模式下编译时不会看到)
作为旁注,这里是您的代码的建议重构(未完全测试并且可能不完整,但您明白了):
static void Main(string[] args)
{
Thread.GetDomain().UnhandledException +=
(sender, eventArgs) => Exiting((Exception)eventArgs.ExceptionObject);
AppDomain.CurrentDomain.ProcessExit +=
(sender, eventArgs) => Exiting(null);
//1 new Thread(_ => { throw new Exception(); }).Start();
//2 ThreadPool.QueueUserWorkItem(_ => { throw new Exception(); });
Thread.Sleep(1000);
return;
}
static void Exiting(Exception exception)
{
//Put common cleanup code here (or at the end of the method)
if(exception == null)
{
Console.WriteLine("normal proc exit");
}
else
{
Console.WriteLine("unhandled exception: " + exception.GetType().Name);
}
}