繁体   English   中英

找出抛出 unobservedTaskException 的位置:stacktrace 为 null

[英]Finding out where unobservedTaskException is thrown: stacktrace is null

我有一个使用第三方库的大型 C# 应用程序,并且在应用程序的某个地方运行了一个未等待并引发异常的任务。

所以我向 TaskScheduler.UnobservedTaskException 添加了一个事件处理程序:

TaskScheduler.UnobservedTaskException += (sender, args) =>
{
    _logger.Error(args.Exception);
    args.SetObserved();
};

但是,当这个处理程序被执行时,我得到一些异常,堆栈跟踪为空:

System.AggregateException: A Task's exception(s) were not observed either by Waiting on the Task or accessing its Exception property. As a result, the unobserved exception was rethrown by the finalizer thread. 
    ---> Grpc.Core.RpcException: Status(StatusCode=Cancelled, Detail="Cancelled")
    --- End of inner exception stack trace ---
---> (Inner Exception #0) Grpc.Core.RpcException: Status(StatusCode=Cancelled, Detail="Cancelled")<---

当我调试这段代码时,args.Exception 的 stacktrace 为 null,我不知道它来自哪里。 我尝试使用 Visual Studio 2017 捕获 System.AggregateException 类型的所有异常,但没有捕获到。 我试图捕获 Grpc.Core.RpcException 类型的所有异常,但其中很多异常都被抛出并仅在用户代码中处理(每秒 10 个),而我未捕获的异常每几个小时只发生一次,所以它是手动跳过应用程序中抛出的所有数千个 RpcExceptions 是不可行的。

我怎么能找出这个未捕获的异常发生的地方? 我尝试在所有任务/异步方法中添加 try/catch 块,但无济于事,尽管我可能错过了一些。 我试图从我的代码中删除所有即发即弃的任务,但我什至不知道这个异常是来自我的代码还是来自外部代码(在这种情况下,我可以向代码的开发人员报告)。

我的应用程序中未等待的异步方法 (async void) 发生在事件处理程序中,我尝试放置 try/catch 块来捕获异常。 但是这个问题仍然存在。

我还能做些什么来弄清楚何时何地抛出此异常以及未观察到的任务可能在哪里?

要解决此类问题,您可以使用像 dotMemory 这样的内存分析器并收集分配( https://www.jetbrains.com/help/dotmemory/dotMemory_Profiler_Options.html )!

当未处理的异常发生时,进行快照,找到任务(可以通过其类型和 id 完成)并查看该实例的创建堆栈跟踪( https://www.jetbrains.com/help/dotmemory/ Creation_Stack_Trace_instance.html )。

下面是一些帮助您入门的代码:

TaskScheduler.UnobservedTaskException += (sender, args) => 
    MessageBox.Show($"Almost there, now take a snapshot and look for the creation stacktrace of {sender.GetType()}, Id={((Task)sender).Id}!");

希望这对你有用,对我有用:)

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM