Reflection MethodInfo.Invoke() 从方法内部捕获异常

发布于 2024-10-01 04:16:58 字数 257 浏览 0 评论 0原文

我调用 MethodInfo.Invoke() 通过反射执行函数。该调用包装在 try/catch 块中,但它仍然无法捕获我正在调用的函数抛出的异常。

我收到以下消息:

用户未处理异常。


为什么 MethodInfo.Invoke() 会阻止在 Invoke() 之外捕获异常?
我该如何绕过它?

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?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

烟凡古楼 2024-10-08 04:16:59

编辑:据我了解您的问题,问题纯粹是 IDE 问题;您不喜欢 VS 将调用 MethodInfo 引发的异常视为未捕获,而事实显然并非如此。您可以在此处阅读有关如何解决此问题的信息: 为什么是 TargetInvocableException是否被 IDE 视为未捕获? 这似乎是一个错误/有意设计;但无论如何,该答案中列出了不错的解决方法。

在我看来,您有几个选择:

  1. 您可以使用 MethodInfo.Invoke,捕获 TargetInvocableException 并检查其 InnerException财产。您必须解决该答案中提到的 IDE 问题。

  2. 您可以从 MethodInfo 创建适当的Delegate 并调用它。使用这种技术,抛出的异常将不会被包装。此外,这种方法似乎与调试器配合得很好。我没有收到任何“未捕获的异常”弹出窗口。

下面是一个突出显示这两种方法的示例:

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

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();
    }
}
暮光沉寂 2024-10-08 04:16:59

您如何尝试捕获异常?通常,调用 Invoke() 引发的异常是 System.Reflection.TargetInvocationException 的包装异常实例。您要处理的实际异常将位于 InnerException 中。

try
{
    method.Invoke(target, params);
}
catch (TargetInvocationException ex)
{
    ex = ex.InnerException; // ex now stores the original exception
}

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
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文