在我们的 WPF 应用程序中,我们为未观察到的任务异常注册了一个事件处理程序:
TaskScheduler.UnobservedTaskException += OnUnobservedTaskException;
用以下方法:
private static void OnUnobservedTaskException(object sender, UnobservedTaskExceptionEventArgs exceptionEventArgs)
{
_logger.Error(exceptionEventArgs.Exception, Properties.Resources.TaskExceptionsWereNotObserved);
exceptionEventArgs.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. (The I/O operation has been aborted because of either a thread exit or an application request.)
---> System.Net.Sockets.SocketException (995): The I/O operation has been aborted because of either a thread exit or an application request.
at System.Net.Sockets.Socket.AwaitableSocketAsyncEventArgs.System.Threading.Tasks.Sources.IValueTaskSource<System.Net.Sockets.SocketReceiveFromResult>.GetResult(Int16 token)
at System.Threading.Tasks.ValueTask`1.ValueTaskSourceAsTask.<>c.<.cctor>b__4_0(Object state)
--- End of inner exception stack trace ---
但是我们的代码中似乎没有任何内容。
我的问题:
有没有办法添加更多调试信息来知道这是在哪里触发的?因为我什至不确定异常发生在我们的代码中还是外部库中。
我建议利用 Handle
AggregateException
方法
对此 AggregateException 包含的每个异常调用处理程序。
private static void OnUnobservedTaskException(object sender, UnobservedTaskExceptionEventArgs exceptionEventArgs)
{
exceptionEventArgs.SetObserved();
((AggregateException)exceptionEventArgs.Exception).Handle(ex =>
{
_logger.Error(ex); //Or whatever you like to do with the exception
return true;
});
}
为了简单起见,我使用了强制转换,但在生产代码中,在进行任何类型转换之前,请确保
exceptionEventArgs.Exception
是 AggregateException
。