我有许多方法是使用Delegate.DynamicInvoke
调用的。其中一些方法会进行数据库调用,我希望能够捕获SqlException
,而不是捕获TargetInvocationException
并搜索其内部以找到实际发生了什么。
我曾尝试使用此方法重新抛出异常,但它清除了堆栈跟踪:
try
{
return myDelegate.DynamicInvoke(args);
}
catch(TargetInvocationException ex)
{
Func<TargetInvocationException, Exception> getInner = null;
getInner =
delegate(TargetInvocationException e)
{
if (e.InnerException is TargetInvocationException)
return getInner((TargetInvocationException) e.InnerException);
return e.InnerException;
};
Exception inner = getInner(ex);
inner.PreserveStackTrace();
throw inner;
}
PreserveStackTrace
方法是我改进的一个扩展方法(我不知道它实际上是做什么的),感谢另一篇帖子。然而,它似乎也没有保留堆栈跟踪:
public static void PreserveStackTrace(this Exception e)
{
var ctx = new StreamingContext(StreamingContextStates.CrossAppDomain);
var mgr = new ObjectManager(null, ctx);
var si = new SerializationInfo(e.GetType(), new FormatterConverter());
e.GetObjectData(si, ctx);
mgr.RegisterObject(e, 1, si);
mgr.DoFixups();
}