当 .NET 线程抛出异常时会发生啥?

Posted

技术标签:

【中文标题】当 .NET 线程抛出异常时会发生啥?【英文标题】:What happens when a .NET thread throws an exception?当 .NET 线程抛出异常时会发生什么? 【发布时间】:2010-12-12 17:20:41 【问题描述】:

我们有一个接口 IPoller,我们有各种实现。我们有一个进程将接受一个 IPoller 并在一个单独的线程中启动它。我试图想出一种通用的方法来为任何不自己做的 IPollers 提供异常处理。

我最初的想法是创建一个接受 IPoller 并仅提供一些日志记录功能的 IPoller 实现。我遇到的问题是我将如何提供这种错误处理?如果我有 IPoller.Start() 这是线程的目标是发生异常的地方吗?或者线程本身有什么我可以挂钩的吗?

【问题讨论】:

【参考方案1】:

类似:

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

这将确保异常不会到达线程的顶部。

【讨论】:

您可能还想捕获 AppDomainUnloadedException。 MSDN:在线程中抛出 AppDomainUnloadedException,因为正在卸载正在执行线程的应用程序域。 我知道您解释了如何防止异常越过线程,但问题标题说“如果它发生了会发生什么”.. 对此有任何指示吗?【参考方案2】:

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

未处理的异常(在线程顶部)将(在 2.0 及更高版本中)终止您的进程。不好。

即无论您传递给Thread.Start(等)的任何方法都应该有一个try/catch,并在catch 中做一些有用的事情(日志记录,可能是正常关闭等)。

为此,您可以使用:

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

【讨论】:

【参考方案3】:

在 .NET 4.0+ 中,您应该使用任务而不是线程。 Here's a nice article 任务并行库中的异常处理

【讨论】:

【参考方案4】:

看看AppDomain.UnhandledException,它至少可以帮助你记录那些你没有处理的异常,并且在某些情况下“很好地”关闭:

此事件提供通知 未捕获的异常。它允许 应用程序记录有关信息 系统前的异常 默认处理程序报告异常 给用户并终止 应用。如果信息足够 关于应用程序的状态是 可用,其他操作可能是 进行——例如储蓄计划 数据以供以后恢复。小心是 建议,因为程序数据可以 当异常发生时被破坏 未处理。

【讨论】:

【参考方案5】:

看看

Appdomain.FirstChanceException event

它会告诉您发生任何异常并且 CLR 正在寻找堆栈跟踪。事件参数也告诉哪种类型的异常。您可以将其视为日志记录的中心位置。

【讨论】:

以上是关于当 .NET 线程抛出异常时会发生啥?的主要内容,如果未能解决你的问题,请参考以下文章

在多线程 C++11 程序中未处理异常时会发生啥?

JAVA语言如何进行异常处理,关键字throws,throw,try,catch,finally分别代表啥意义在try块中抛出异常吗

java中如果在关闭Socket时发生一个I/O错误,则会抛出一个啥异常?

在线程中处理在 catch 块中抛出的异常的最佳实践。 (。网)

为啥在 ios/cordova 中抛出这个异常?

当自动关闭资源时尝试使用资源引发异常以及异常时会发生啥