c# - 如何在 AppDomain.CurrentDomain.UnhandledException 处理程序中退出应用程序并仍然确保 finally{} block 执行?

标签 c# .net exception try-catch-finally

我希望防止在发生异常时出现“应用程序已停止工作”弹出窗口。一种方法显然是在全局异常处理程序中调用Environment.Exit(1),即AppDomain.CurrentDomain.UnhandledException,如下所示:

static void CurrentDomain_UnhandledException(object sender, UnhandledExceptionEventArgs e)
{            
    Exception exc = (Exception)e.ExceptionObject;
    Console.Error.WriteLine("Exception:\n{0}", exc.Message);
    Console.Error.WriteLine("Stack trace:\n{0}", exc.StackTrace);

    Environment.Exit(1);    // quit silently on exception, don't show the popup                    
}

但是,由于执行顺序,上述代码导致 finally block 未执行。此类行为的一个简单示例:

    AppDomain.CurrentDomain.UnhandledException += new UnhandledExceptionEventHandler(CurrentDomain_UnhandledException);
    try
    {
        Console.WriteLine("try block");
        throw new Exception("Somebody set us up the bomb.");
    }
    catch
    {
        Console.Error.WriteLine("catch block");
        throw;
    }
    finally
    {
        Console.WriteLine("finally block");
    }
在应用程序退出之前,异常处理程序中的

Environment.Exit(1) 会产生以下输出(注意没有finally block ):

try block
catch block
Exception:
      Somebody set us up the bomb.
Stack trace:
       at ...

finally block 执行至关重要时,这可能会导致严重的问题,例如清理 try 中创建的临时文件时。

有没有一种简单的方法可以解决这一切?也就是说,保留全局异常处理程序,在其中自定义异常输出等,然后优雅退出,但仍然得到 finally block 来执行。我觉得很奇怪,像this这样的问题中没有提到这个问题。 .

最佳答案

你不会得到这个。 Environment.Exit() 确保终结器仍然运行,这可能是后备方案。但不适用于清理临时文件,请使用操作系统对此的支持并使用 FileOptions.DeleteOnClose 选项。

一般来说,你不应该依赖清理的硬性要求,当 CLR 用 SOE 或 FEEE 轰炸、用户从任务管理器终止你的应用程序、硬重启机器或电源关闭时,没有任何东西会被清理。 .

关于c# - 如何在 AppDomain.CurrentDomain.UnhandledException 处理程序中退出应用程序并仍然确保 finally{} block 执行?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18533360/

相关文章:

c# - 视觉画笔作为 ContextMenu wpf 中的图标

c# - 在文件路径中复制文件夹结构的函数

c# - 异常从非托管代码传播到托管代码?

java - 如何从 web 服务中抛出异常?

java - 太阳.awt.image.PNGImageDecoder$PNGException : crc corruption

c# - 生成不重复的随机数.C#

c# - 如何将 var 类型转换为 int?

c# - 当绑定(bind)属性声明为接口(interface)类型与类类型时,WPF 绑定(bind)行为不同?

c# - WPF - 将窗口置于最前面

c# - 在 wpf c# 中单击更改按钮图像