当一个.NET线程抛出异常时会发生什么?

19

我们有一个接口IPoller,有多种不同的实现。我们有一个处理过程,它将获取一个IPoller并在单独的线程中启动它。我正在尝试想出一种通用的方法来为任何未自行处理异常的IPoller提供异常处理。

我的最初想法是创建一个IPoller的实现,该实现将接受一个IPoller并提供一些日志记录功能。但我遇到的问题是,如何提供这个错误处理?如果我有一个IPoller.Start()作为线程的目标,那么异常会发生在哪里?还是有什么东西可以钩入到线程本身中呢?

5个回答

21

类似这样:

Thread thread = new Thread(delegate() {
    try
    {
        MyIPoller.Start();
    }
    catch(ThreadAbortException)
    {
    }
    catch(Exception ex)
    {
        //handle
    }
    finally
    {
    }
});

这样做将确保异常不会传播到线程的顶部。


您可能还想捕获AppDomainUnloadedException异常。MSDN:在线程中抛出AppDomainUnloadedException异常,因为正在卸载执行线程的应用程序域。 - Mihail Shishkov
我知道你已经解释了如何防止异常跨线程,但问题标题说“如果发生异常会发生什么”.. 对此有什么建议吗? - eRaisedToX

13

在线程的顶部使用您所使用方法的异常捕获,并从那里进行记录。

未经处理的异常(在线程的顶部)将会(从2.0版本开始)终止进程。这不是好的情况。

例如,您通过Thread.Start传递的任何方法应该有一个try/catch语句,并在catch块中做一些有用的事情(例如记录日志、优雅关闭等)。

为了实现这一点,您可以使用:

  • 静态记录方法
  • 将变量捕获到委托中(作为匿名方法)
  • 在已知记录器的实例上公开您的方法

8
在.NET 4.0+中,您应该使用Tasks而不是threads。这里有一篇关于Task Parallel Library异常处理的好文章。请参考此处

4

请查看AppDomain.UnhandledException,它可以帮助你至少记录那些未被处理的异常,并在某些情况下安全地关闭应用程序:

此事件提供了未捕获异常的通知。它允许应用程序在系统默认处理程序报告异常并终止应用程序之前记录有关异常的信息。如果可用于应用程序状态的足够信息,则可以采取其他操作,例如保存程序数据以备后续恢复。需要注意的是,如果不处理异常,则可能会导致程序数据损坏。


0

请看一下

Appdomain.FirstChanceException事件

它会告诉你任何异常发生的时刻,以及CLR正在寻找堆栈跟踪。此外,事件参数还会告诉你异常的类型。你可以将其视为日志记录的中心位置。


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