356 votes

En C #, comment puis-je relancer InnerException sans perdre la trace de la pile?

J'appelle, par la réflexion, une méthode qui peut provoquer une exception. Comment puis-je transmettre l'exception à mon appelant sans que la réflexion de l'enveloppe ne la contourne? Je réécrit l'InnerException, mais cela détruit la trace de la pile. Exemple de code:

     public void test1()
    {
        // Throw an exception for testing purposes
        throw new ArgumentException("test1");
    }

    void test2()
    {
        try
        {
            MethodInfo mi = typeof(Program).GetMethod("test1");
            mi.Invoke(this, null);
        }
        catch (TargetInvocationException tiex)
        {
            // Throw the new exception
            throw tiex.InnerException;
        }
    }
 

567voto

Tragedian Points 12308

Dans .NET 4.5 , il est maintenant l' ExceptionDispatchInfo classe.

Cela vous permet de capturer une exception et re-jeter sans modification de la pile-trace:

try
{
    task.Wait();
}
catch(AggregateException ex)
{
    ExceptionDispatchInfo.Capture(ex.InnerException).Throw();
}

Cela fonctionne sur aucune exception, pas seulement AggregateException.

Il a été introduit en raison de l' await C# pour le langage, qui déballe l'intérieur des exceptions AggregateException instances afin de faire de l'asynchrone fonctionnalités de langage de plus comme le synchrone fonctionnalités de langage.

88voto

Anton Tykhyy Points 12680

Il est possible de conserver la trace de la pile avant de lever une nouvelle fois sans réflexion :

Cela gaspille beaucoup de cycles par rapport à l’appel de `` via le délégué mis en cache, mais il a l’avantage de se fonder uniquement sur la fonction publique. Voici quelques modèles d’utilisation commune pour fonctions conserver trace de la pile :

36voto

GEOCHET Points 13787

Je pense que le mieux serait de juste mettre ceci dans votre bloc catch :

Et puis extrayez l’innerexception plus tard.

15voto

Eric Points 91
<pre><code></code><p>Appelez la méthode d’extension sur votre exception avant de vous lancer, il conservera la trace de la pile originale.</p></pre>

11voto

skolima Points 12221

Encore plus de réflexion...

N’oubliez pas que cela risque d’altérer à tout moment, comme les champs privés ne font pas partie de l’API. Voir aussi discussion sur bugzilla Mono.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X