gpt4 book ai didi

c# - 如何在维护到目前为止生成的堆栈跟踪的同时重新抛出内部异常?

转载 作者:IT王子 更新时间:2023-10-29 04:41:40 25 4
gpt4 key购买 nike

副本:In C#, how can I rethrow InnerException without losing stack trace?

我有一些在后台线程上异步调用的操作。有时,事情会变糟。发生这种情况时,我往往会得到一个 TargetInvocationException,它虽然合适,但却毫无用处。我真正需要的是 TargetInvocationException 的 InnerException,如下所示:

    try
{
ReturnValue = myFunctionCall.Invoke(Target, Parameters);
}
catch (TargetInvocationException err)
{
throw err.InnerException;
}

那样的话,我的调用者就会得到真正发生的异常。问题是,throw 语句似乎重置了堆栈跟踪。我想基本上重新抛出内部异常,但保留它最初的堆栈跟踪。我该怎么做?

澄清:我只想要内部异常的原因是此类试图“抽象掉”这些函数(由调用者提供的委托(delegate))在其他线程上运行的整个事实等等。如果有异常,那么很可能它与在后台线程上运行无关,调用者真的希望堆栈跟踪进入他们的委托(delegate)并找到真正的问题,而不是我调用调用。

最佳答案

可以在没有反射的情况下重新抛出之前保留堆栈跟踪:

static void PreserveStackTrace (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) ; // prepare for SetObjectData
mgr.DoFixups () ; // ObjectManager calls SetObjectData

// voila, e is unmodified save for _remoteStackTraceString
}

与 InternalPreserveStackTrace 相比,这浪费了很多周期,但具有仅依赖公共(public)功能的优势。以下是堆栈跟踪保留函数的几个常见使用模式:

// usage (A): cross-thread invoke, messaging, custom task schedulers etc.
catch (Exception e)
{
PreserveStackTrace (e) ;

// store exception to be re-thrown later,
// possibly in a different thread
operationResult.Exception = e ;
}

// usage (B): after calling MethodInfo.Invoke() and the like
catch (TargetInvocationException tiex)
{
PreserveStackTrace (tiex.InnerException) ;

// unwrap TargetInvocationException, so that typed catch clauses
// in library/3rd-party code can work correctly;
// new stack trace is appended to existing one
throw tiex.InnerException ;
}

关于c# - 如何在维护到目前为止生成的堆栈跟踪的同时重新抛出内部异常?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1009762/

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