我怎样才能重新抛出内部异常,同时保持至今产生的堆栈跟踪? [英] How can I rethrow an Inner Exception while maintaining the stack trace generated so far?

查看:174
本文介绍了我怎样才能重新抛出内部异常,同时保持至今产生的堆栈跟踪?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

复制:<一href="http://stackoverflow.com/questions/57383/in-c-how-can-i-rethrow-innerexception-without-losing-stack-trace">http://stackoverflow.com/questions/57383/in-c-how-can-i-rethrow-innerexception-without-losing-stack-trace

我有一些操作,我异步调用在后台线程。有时候,事情变坏。发生这种情况时,我往往会得到一个TargetInvocationException,其中,而相应的,还是蛮有用的。我真正需要的是TargetInvocationException的的InnerException,像这样的:

I have some operations that I invoke asynchronously on a background thread. Sometimes, things go bad. When this happens, I tend to get a TargetInvocationException, which, while appropriate, is quite useless. What I really need is the TargetInvocationException's InnerException, like this:

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

这样的话,我的来电都提供了所发生真正的例外。问题是,该throw语句似乎重置堆栈跟踪。我想基本上再次引发内部异常,但保留堆栈跟踪它原本。我该怎么办呢?

That way, my callers are served up with the REAL exception that occured. The problem is, that the throw statement seems to reset the stack trace. I'd like to basically rethrow the inner exception, but keep the stack trace it originally had. How do I do that?

澄清: 我想原因只有内部异常的是,这个类尝试'抽象掉整个事实是,这些功能(通过调用者提供代表)的其他线程和诸如此类的东西运行。如果有一个例外,那么赔率是它无关,与正在运行一个后台线程,调用者会很喜欢那个进入他们的代表,并认为真正的问题,不是我的电话调用堆栈跟踪。

CLARIFICATION: The reason I want only the inner exception is that this class tries to 'abstract away' the whole fact that these functions (delegates supplied by caller) are run on other threads and whatnot. If there is an exception, then odds are it has nothing to do with being run on a background thread, and the caller would really like the stack trace that goes into their delegate and finds the real issue, not my call to invoke.

推荐答案

可能preserve堆栈跟踪重新抛出,而不反思之前:

It is possible to preserve the stack trace before rethrowing without reflection:

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
}

这浪费了大量的周期相比,内部preserveStackTrace的,但只对公共功能依靠的优势。以下是堆栈跟踪preserving功能的几个常见的使用方式:

This wastes a lot of cycles compared to InternalPreserveStackTrace, but has the advantage of relying only on public functionality. Here are a couple of common usage patterns for stack-trace preserving functions:

// 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 ;
}

这篇关于我怎样才能重新抛出内部异常,同时保持至今产生的堆栈跟踪?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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