Réflexion MethodInfo.Invoke() de capturer des exceptions de l'intérieur de la méthode

j'ai un appel à MethodInfo.Invoke() pour exécuter une fonction par la réflexion. L'appel est enveloppé dans un bloc try/catch mais il ne va toujours pas attraper l'exception lancée par la fonction que j'invoque.

je reçois le message suivant:

L'Exception

n'a pas été entravée par l'utilisateur.



Pourquoi ne MethodInfo.Invoke() prévenir l'Exception d'être pris à l'extérieur de la Invoke() ?

Comment dois-je l'ignorer?

21
demandé sur newfurniturey 2010-11-07 12:52:20

2 réponses

EDIT: comme je comprends votre problème, le problème est purement un IDE; vous n'aimez pas VS traiter l'exception lancée par l'invocation du MethodInfo comme non tirée, alors qu'il est clair qu'elle ne l'est pas. Vous pouvez lire sur la façon de résoudre ce problème ici: pourquoi TargetInvocationException est-il traité comme uncaught par L'IDE? il semble qu'il s'agisse d'un bogue / de par sa conception; mais d'une façon ou d'une autre, des solutions de rechange décentes sont énumérées dans cette réponse.

comme je le vois, vous avez deux options:

  1. vous pouvez utiliser MethodInfo.Invoke , attraper le TargetInvocationException et inspecter sa propriété InnerException . Vous devrez contourner les problèmes D'IDE mentionnés dans cette réponse.

  2. vous pouvez créer un Delegate approprié à partir du MethodInfo et invoquer à la place. Avec cette technique, l'exception ne sera pas emballé. En outre, cette approche ne semble bien fonctionner avec le débogueur; Je ne reçois pas de pop-ups" uncaught exception".

voici un exemple qui met en évidence les deux approches:

class Program
{
    static void Main()
    {
        DelegateApproach();
        MethodInfoApproach();
    }

    static void DelegateApproach()
    {
        try
        {
            Action action = (Action)Delegate.CreateDelegate
                                   (typeof(Action), GetMethodInfo());
            action();
        }
        catch (NotImplementedException nie)
        {

        }
     }

    static void MethodInfoApproach()
    {
        try
        {
            GetMethodInfo().Invoke(null, new object[0]);
        }
        catch (TargetInvocationException tie)
        {
            if (tie.InnerException is NotImplementedException)
            {


            }
        }
    }

    static MethodInfo GetMethodInfo()
    {
        return typeof(Program)
                .GetMethod("TestMethod", BindingFlags.NonPublic | BindingFlags.Static);
    }    

    static void TestMethod()
    {
        throw new NotImplementedException();
    }
}
24
répondu Ani 2017-05-23 10:31:25

comment essayez-vous d'attraper l'exception? Typiquement ce qui est lancé d'un appel à Invoke() est une instance d'exception d'emballage de System.Reflection.TargetInvocationException . L'exception que vous cherchez sera dans le InnerException .

try
{
    method.Invoke(target, params);
}
catch (TargetInvocationException ex)
{
    ex = ex.InnerException; // ex now stores the original exception
}
17
répondu Quick Joe Smith 2010-11-07 10:49:39