全局异常处理程序与UnhandledExceptionEventArgs无法工作

3
阅读完thisMSDN页面后,我在我的.NET类库中创建了一个全局异常处理程序,用于记录日志,其代码如下:
    static void OnException(object sender, UnhandledExceptionEventArgs args)
    {
        Exception ex = (Exception)args.ExceptionObject;
        Logging.LogException(ex);
    }

但是,如果我从一个方法中throw new UnauthorizedAccessException()throw new Exception(),这根本不会捕获它。
MSDN页面上说:
UnhandledExceptionEventArgs提供了对异常对象和一个指示公共语言运行时是否正在终止的标志的访问。 UnhandledExceptionEventArgs是传递到AppDomain.UnhandledException事件的UnhandledExceptionEventHandler的参数之一。
我相信我所做的属于AppDomain(而不是ThreadException)?我在这里做错了什么?
PS。我试图避免使用try-catch块,因为显然这是不好的实践。这个类库是从运行周期性的Windows服务中调用的,所以我宁愿不让它“崩溃”,以避免由于未预见的异常而导致的内存泄漏,并且更喜欢定期监视事件日志。

这个方法本身什么也不做。你订阅了UnhandledException事件吗?如果你从阅读链接的问答中得出的结论是“使用try-catch是一种不好的实践”,那么你可能需要再次阅读它。 - CodeCaster
是的,这就是问题所在。虽然我没有main方法,但我应该在哪里订阅呢?至于附件,它在粗体字中说到了。我确实同意它详细地介绍了这个问题,但即使答案谈到日志记录,它也谈到了记录并允许应用程序崩溃。我正在尝试避免这种情况。 - reggaemahn
它说“没有充分的理由”。无论如何,你不应该从类库中这样做。如何处理异常取决于使用应用程序。 - CodeCaster
2个回答

4

为了触发异常处理程序,您需要在当前应用程序域中安装异常处理程序:

AppDomain.CurrentDomain.UnhandledException += OnException;

否则,它只是一个永远不会被调用的方法声明。

是的,这就是订阅事件的方式。然而,这并不是 OP 问题的解决方案,尽管他们已经接受了这个答案。UnhandledException 事件仅向您提供未处理异常的 _通知_。您无法在那里进行 _处理_,而且您绝对不希望在 OP 声称正在编写的 库代码 中执行此操作,因为您将收到应用程序域中 所有 未处理的异常的通知。 - CodeCaster

2

您提到您正在尝试避免使用try catch,但在处理程序内部,这并不是一个坏主意:

static void OnException(object sender, UnhandledExceptionEventArgs args)
{
    try
    {
        Exception ex = (Exception)args.ExceptionObject;
        Logging.LogException(ex);
    }
    catch
    {
       // do nothing to silently swallow error, or try something else...
    }
}

因为您不希望在错误处理程序中出现异常。如果稳定性是首要的,可以将其吞下,或者尝试使用次要(更基本)的日志记录方法来确保没有异常掉落。
通常情况下,静默地吞下异常是一种不好的做法,但这是在一个错误处理块内,其中失败意味着崩溃应用程序。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接