当.NET线程抛出exception时会发生什么?

我们有一个接口IPoller,我们有各种各样的实现。 我们有一个进程将接受一个I​​Poller并在一个单独的线程中启动它。 我正在尝试提出一种通用方法,为任何不自行处理的IPoller提供exception处理。

我最初的想法是创建一个接受IPoller的IPoller实现,并提供一些日志function。 我遇到的问题是如何提供此error handling? 如果我有IPoller.Start()这是Thread的目标,那将发生exception? 或者我可以挂钩的线程本身有什么东西?

就像是:

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

这将确保exception不会使其成为线程的顶部。

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

未处理的exception(在线程顶部)将(在2.0以后)终止您的进程。 不好。

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

为此,您可以使用:

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

在.NET 4.0+中,您应该使用Tasks而不是线程。 这是关于任务并行库中exception处理的一篇很好的文章

看看AppDomain.UnhandledException ,它将帮助您至少记录那些您未处理的exception,并在某些情况下“很好地”关闭:

此事件提供未捕获exception的通知。 它允许应用程序在系统默认处理程序向用户报告exception并终止应用程序之前记录有关exception的信息。 如果有足够的有关应用程序状态的信息,则可以采取其他措施 – 例如保存程序数据以便以后恢复。 建议小心,因为在未处理exception时程序数据可能会损坏。

看一下

Appdomain.FirstChanceException事件

它告诉你任何exception发生的时刻,CLR正在寻找堆栈跟踪。 事件参数也告诉了哪种类型的exception。 您可以将其视为记录的中心位置。