gpt4 book ai didi

c#-4.0 - Exception.GetBaseException() 返回不为 null InnerException 的异常

转载 作者:行者123 更新时间:2023-12-02 21:35:13 29 4
gpt4 key购买 nike

我有一个 System.AggregateException 类型的异常:

Message = "One or more errors occurred."
Source = null
StackTrace = null

它的InnerException是这个System.Reflection.TargetInvocationException:

Message = "Exception has been thrown by the target of an invocation."
Source = "mscorlib"
StackTrace =
at System.RuntimeMethodHandle.InvokeMethod(Object target, Object[] arguments, Signature sig, Boolean constructor)
at System.Reflection.RuntimeMethodInfo.UnsafeInvokeInternal(Object obj, Object[] parameters, Object[] arguments)
at System.Reflection.RuntimeMethodInfo.Invoke(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture)
at System.Reflection.MethodBase.Invoke(Object obj, Object[] parameters)
at Microsoft.AspNet.SignalR.Hubs.HubDispatcher.Incoming(IHubIncomingInvokerContext context)

它的InnerException是我创建的异常,它扩展自ApplicationException:

Message = "Some error writen by me at the hub"
Source = "Chat"
StackTrace =
at Chat.Hubs.ChatHub.SendMessage(String text, String clientConnId) in d:\...Chat\Chat\Hubs\ChatHub.cs:line 48

当我运行这个时:

Exception excpetion = ex.GetBaseException();

其中exSystem.AggregateException,我在excpetion处得到了System.Reflection.TargetInvocationException这怎么会发生?

场景

我不知道如何在一个简单的项目中重现这个。就我而言,我在 SignalR 项目中发现了这一点。某些集线器方法抛出异常并在 global.asax 中处理错误:

GlobalHost.HubPipeline.AddModule(new MyHubPipelineModule());

并且MyHubPipelineModule应该是这样的:

public class MyHubPipelineModule : HubPipelineModule
{
protected override void OnIncomingError(Exception ex, IHubIncomingInvokerContext context)
{
Exception excpetion = ex.GetBaseException();
context.Hub.Clients.Caller.ExceptionHandler(excpetion.Message);
}
}

注意:这应该使用 SignalR 1.0.1 来完成。在 1.1.0 中,异常更简单(更小的链),因此它运行良好。确保您有此软件包版本:

<package id="Microsoft.AspNet.SignalR" version="1.0.1" targetFramework="net40" />
<package id="Microsoft.AspNet.SignalR.Core" version="1.0.1" targetFramework="net40" />
<package id="Microsoft.AspNet.SignalR.JS" version="1.0.1" targetFramework="net40" />
<package id="Microsoft.AspNet.SignalR.Owin" version="1.0.1" targetFramework="net40" />
<package id="Microsoft.AspNet.SignalR.SystemWeb" version="1.0.1" targetFramework="net40" />

最佳答案

根据 MSDN GetBaseException应该表现得像

public Exception GetBaseException()
{
Exception result = this;
while (result.InnerException != null)
result = result.InnerException;
return result;
}

和状态

For all exceptions in a chain of exceptions, the GetBaseException method must return the same object (the base exception).

这就引出了一个问题,为什么这个方法是虚拟的?看起来任何覆盖都只能匹配实现或违反契约(Contract)。

根据 MSDN AggregateException.GetBaseException

Returns the AggregateException that is the root cause of this exception.

根据OP的声明(以及对源代码的检查),“返回AggregateException”可能会被违反,因为结果并不总是 AggregateException。

坦率地说,我发现整个声明是不合逻辑的,因为我认为“第一个”NON-AggregateException 是“此异常的根本原因”,因为人们可以识别单个(“the”)根原因。由于“常规”异常只是在朝着并行处理“扇出”的根源移动时被封装在 AggregateExceptions 中。

的最佳解释是 AggregateException.GetBaseException 旨在“展开”毫无意义的非并行嵌套 AggregateException,直到达到实际发生“扇出”的级别。

这里的错误(稍后修复)似乎是在没有“扇出”时发生的情况,即只有一个(非聚合)InnerException 的 AggregateException。在这种情况下,它返回该(非聚合)异常。 ....它有不同的 GetBaseException 实现/解释。

2020 年编辑:在随后几年的某个时刻 AggregateException.GetBaseException's implementation已修复以匹配上述解释。 @Jan-Slodicka 的回答表明它至少早在 2016 年就在 Mono 中得到了修复。

关于c#-4.0 - Exception.GetBaseException() 返回不为 null InnerException 的异常,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16565834/

29 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com