c# - 如何捕获/观察任务抛出的未处理异常

标签 c# .net wpf exception-handling task-parallel-library

我正在尝试记录/报告我的应用中所有未处理的异常(错误报告解决方案)。我遇到过一个始终未处理的场景。我想知道如何以未处理的方式捕获此错误。请注意,我今天早上做了很多研究并尝试了很多东西。是的,我已经看到了 this , this还有很多。我只是在寻找一种通用解决方案来记录未处理的异常。

我在控制台测试应用程序的主要方法中有以下代码:

Task.Factory.StartNew(TryExecute);

Task.Run((Action)TryExecute);

还有下面的方法:

private static void TryExecute() {
   throw new Exception("I'm never caught");
}

我已经尝试在我的应用中连接到以下内容,但从未调用过它们。

AppDomain.CurrentDomain.UnhandledException
TaskScheduler.UnobservedTaskException

在我最初发现此错误的 Wpf 应用程序中,我也连接了这些事件,但从未调用过。

Dispatcher.UnhandledException
Application.Current.DispatcherUnhandledException
System.Windows.Forms.Application.ThreadException

唯一被调用的处理程序是:

AppDomain.CurrentDomain.FirstChanceException

但这不是一个有效的解决方案,因为我只想报告未捕获的异常(不是每个异常都在执行/解析任何 catch block 之前调用 FirstChanceException。

最佳答案

TaskScheduler.UnobservedTaskException 事件应该给你你想要的,正如你上面所说的。是什么让您认为它没有被解雇?

在特定情况下,异常会被任务捕获然后重新抛出,但不是立即。任务的异常会以多种方式重新抛出(我没想到,可能还有更多)。

  1. 当您尝试访问结果时 (Task.Result)
  2. 调用 Wait()Task.WaitOne()Task.WaitAll() 或其他相关的 Wait 任务方法。
  3. 当您尝试在未明确查看或处理异常的情况下处置任务时

如果您执行上述任何操作,异常将在代码运行的任何线程上重新抛出,并且事件将不会被调用,因为您将观察 异常。如果您没有 try {} catch {} 中的代码,您将触发 AppDomain.CurrentDomain.UnhandledException,这听起来像是可能发生的事情。

另一种重新抛出异常的方式是:

  • 当您不执行上述任何操作时,任务仍将异常视为未观察到并且任务正在完成。它作为最后的努力被抛出,让您知道存在您没有看到的异常。

如果是这种情况,并且由于终结器是不确定的,您是否正在等待 GC 发生,以便将那些具有未观察到的异常的任务放入终结器队列,然后再次等待它们被终结?

编辑:This article谈一点这个。 And this article讨论事件存在的原因,这可能会让您深入了解如何正确使用它。

关于c# - 如何捕获/观察任务抛出的未处理异常,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19164556/

相关文章:

c# - Return 和 finally 子句 - 不一致的行为

c# - 没有虚拟化的 WPF DataGrid 性能

c# - 图像缩放后我如何更新滚动查看器?

c# - 如何使用 WPF 业务应用程序从 Outlook 获取有关当前用户通讯组列表的信息

c# - 如何在Unity中制作登录窗口

c# - SharpSvn GetInfo LastChangeRevision 错误

c# - 为什么 DependencyProperty.UnsetValue 被传递到 Equals()

c# - 包装 C 结构以在 WPF 应用程序中进行访问

c# - 从 cmdlet 中调用 PSCmdlet

c# - c#中数值递增的问题