我正在尝试记录/报告我的应用中所有未处理的异常(错误报告解决方案)。我遇到过一个始终未处理的场景。我想知道如何以未处理的方式捕获此错误。请注意,我今天早上做了很多研究并尝试了很多东西。是的,我已经看到了 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
事件应该给你你想要的,正如你上面所说的。是什么让您认为它没有被解雇?
在特定情况下,异常会被任务捕获然后重新抛出,但不是立即。任务的异常会以多种方式重新抛出(我没想到,可能还有更多)。
- 当您尝试访问结果时 (
Task.Result
) - 调用
Wait()
、Task.WaitOne()
、Task.WaitAll()
或其他相关的Wait
任务方法。 - 当您尝试在未明确查看或处理异常的情况下处置任务时
如果您执行上述任何操作,异常将在代码运行的任何线程上重新抛出,并且事件将不会被调用,因为您将观察 异常。如果您没有 try {} catch {}
中的代码,您将触发 AppDomain.CurrentDomain.UnhandledException
,这听起来像是可能发生的事情。
另一种重新抛出异常的方式是:
- 当您不执行上述任何操作时,任务仍将异常视为未观察到并且任务正在完成。它作为最后的努力被抛出,让您知道存在您没有看到的异常。
如果是这种情况,并且由于终结器是不确定的,您是否正在等待 GC 发生,以便将那些具有未观察到的异常的任务放入终结器队列,然后再次等待它们被终结?
编辑:This article谈一点这个。 And this article讨论事件存在的原因,这可能会让您深入了解如何正确使用它。
关于c# - 如何捕获/观察任务抛出的未处理异常,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19164556/