How can I rethrow an Inner Exception while maintaining the stack trace generated so far?

后端 未结 8 1927
春和景丽
春和景丽 2021-01-31 05:03

Duplicate of: In C#, how can I rethrow InnerException without losing stack trace?

I have some operations that I invoke asynchronously on a background thread. Sometimes,

8条回答
  •  礼貌的吻别
    2021-01-31 05:45

    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
    }
    

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

提交回复
热议问题