找出抛出 unobservedTaskException 的位置:stacktrace 为 null [英] Finding out where unobservedTaskException is thrown: stacktrace is null

查看:29
本文介绍了找出抛出 unobservedTaskException 的位置:stacktrace 为 null的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I have a large C# appication using third party libraries and somewhere in the application a task is run which is not awaited and throws an exception.

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

So I added an event handler to TaskScheduler.UnobservedTaskException:

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

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

However, when this handler is executed, I get some exception with a stacktrace of null:

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 是不可行的.

When I debug this code, the stacktrace of args.Exception is null and I don't know where it comes from. I tried to catch all exceptions of type System.AggregateException using visual studio 2017, but none was caught. I tried to catch all exceptions of type Grpc.Core.RpcException, but a lot of those are thrown and just handled in user code (in the order of 10 per second), while my uncaught exception happens only once every few hours so it is not feasible to skip manually through all the thousands of RpcExceptions thrown in the application.

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

How can I ever find out where this uncaught exception happens? I tried adding try/catch blocks in all tasks/async methods, but to no avail, though I might have missed some. I tried to remove all fire-and-forget tasks from my code, but I don't even know if this exception is from my code or from external code (in which case I could report to the code's developer).

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

unawaited async methods (async void) in my app occur in event handlers, and there I tried to put try/catch blocks to catch the exception. But still this issue persists.

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

What else could I do to figure out when and where this exception is thrown and where the unobserved task could be?

推荐答案

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

To solve this sort of problem, you can use a memory profiler like dotMemory and collect allocations (https://www.jetbrains.com/help/dotmemory/dotMemory_Profiler_Options.html)!

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

When the unhandled exception happens, take a snapshot, find the task (can be done by its type and id) and have a look at the creation stack trace of that instance (https://www.jetbrains.com/help/dotmemory/Creation_Stack_Trace_instance.html).

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

Here's some code to get you started:

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}!");

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

Hope this works for you, it did for me :)

这篇关于找出抛出 unobservedTaskException 的位置:stacktrace 为 null的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆