Reflection MethodInfo.Invoke() catch exceptions fr

2019-01-09 11:57发布

I have a call to MethodInfo.Invoke() to execute a function through reflection. The call is wrapped in a try/catch block but it still won't catch the exception thrown by the function I'm invoking.

I receive the following message:

Exception was unhandled by the user.


Why does MethodInfo.Invoke() prevent the Exception to be caught outside of the Invoke()?
How do I bypass it?

2条回答
爷的心禁止访问
2楼-- · 2019-01-09 12:33

EDIT: As I understand your issue, the problem is purely an IDE one; you don't like VS treating the exception thrown by the invocation of the MethodInfo as uncaught, when it clearly isn't. You can read about how to resolve this problem here: Why is TargetInvocationException treated as uncaught by the IDE? It appears to be a bug / by design; but one way or another, decent workarounds are listed in that answer.

As I see it, you have a couple of options:

  1. You can use MethodInfo.Invoke, catch the TargetInvocationException and inspect its InnerException property. You will have to workaround the IDE issues as mentioned in that answer.

  2. You can create an appropriate Delegate out of the MethodInfo and invoke that instead. With this technique, the thrown exception will not be wrapped. Additionally, this approach does seem to play nicely with the debugger; I don't get any "Uncaught exception" pop-ups.

Here's an example that highlights both approaches:

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();
    }
}
查看更多
smile是对你的礼貌
3楼-- · 2019-01-09 12:33

How are you trying to catch the exception? Typically what is thrown from a call to Invoke() is a wrapping exception instance of System.Reflection.TargetInvocationException. The actual exception you're after will be in the InnerException.

try
{
    method.Invoke(target, params);
}
catch (TargetInvocationException ex)
{
    ex = ex.InnerException; // ex now stores the original exception
}
查看更多
登录 后发表回答