启用下面的第//1
行将导致程序崩溃,而不会打印“ proc exit”,
但在第//2
行的情况下,将打印“ proc exit”。在两种情况下都将打印“未处理的” btw。
为什么会有区别,一般规则是什么?显然使用例如任务管理器将阻止打印“ proc exit”,但除此之外,在什么情况下无法打印?
static void Main(string[] args)
{
Thread.GetDomain().UnhandledException +=
(sender, eventArgs) => Console.WriteLine("unhandled");
AppDomain.CurrentDomain.ProcessExit +=
(sender, eventArgs) => Console.WriteLine("proc exit");
//1 new Thread(_ => { throw new Exception(); }).Start();
//2 ThreadPool.QueueUserWorkItem(_ => { throw new Exception(); });
Thread.Sleep(1000);
return;
最佳答案
两种情况之间没有区别,很难解释为什么会看到这种情况。
使用编写的代码,永远不要引发AppDomain.ProcessExit事件。正常的事情应该发生,CLR将异常传递给操作系统,然后弹出Windows错误报告崩溃对话框。如果异常是程序崩溃的已知原因(不会),它会花一会儿时间与Microsoft服务器进行检查,然后在用户关闭对话框时终止该程序。因此没有ProcessExit事件。
您当然可以编写代码,以便引发ProcessExit。它要求您不要让操作系统来处理它。您必须自己关闭程序。通过使用AppDomain.UnhandledException事件处理程序自己显式终止程序来执行此操作。像这样:
Thread.GetDomain().UnhandledException += (s, e) => {
var ex = (Exception)e.ExceptionObject;
Console.WriteLine(ex.ToString());
Environment.Exit(System.Runtime.InteropServices.Marshal.GetHRForException(ex));
};
您确实可以选择如何终止程序。我显示了Environment.Exit(),但您也可以考虑Environment.FailFast()要求立即中止而无需运行任何其他代码。这样比较安全,但是当然您也不会获得ProcessExit。