启用下面的第//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。

08-17 15:07