c#中不从反射方法调用传播的异常

本文关键字:调用 传播 异常 方法 反射 | 更新日期: 2023-09-27 18:13:40

通过methodInfo调用方法时。调用,如果抛出异常,它似乎不会传播到我的catch块。

object value;
try
{
    value = myMethod.Invoke(null, parameters);//program crashes with uncaught exception
}
catch
{
    throw new Exception("Caught!");//never executed
}

这个方法引发的特殊异常是KeyNotFoundException,但这应该无关紧要,因为我正在捕捉所有对吗?

我从Visual Studio得到的错误信息是

KeyNotFoundException was unhandled by user code

而通常消息会说

KeyNotFoundException was unhandled

如果调用不是反射调用。

我可以只是有方法检查,看看他们的关键是在那里,如果不返回null,但使用异常处理似乎更可取。是否有任何方法从反射的方法调用传播异常?

c#中不从反射方法调用传播的异常

这也可能是Visual Studio调试器的问题。正如对这个类似问题的公认答案所指出的那样,您可以采取一些变通措施。其中最简单的是更改Visual Studio调试器,在Tools -> Options -> Debugging -> General中关闭"Just My Code"。您还可以将其包装在委托中,或者显式地尝试捕获调用异常并检查该异常的内部异常,该异常应该是KeyNotFoundException。

它适合我:

using System;
using System.Reflection;
class Program
{
    static void Main(string[] args)  
    {
        var method = typeof(Program).GetMethod("ThrowException");
        try
        {
            method.Invoke(null, null);
        }
        catch (TargetInvocationException e)
        {
            Console.WriteLine("Caught exception: {0}", e.InnerException);
        }
    }
    public static void ThrowException()
    {
        throw new Exception("Bang!");
    }
}

请注意,您确实需要捕获TargetInvocationException,这是由Method.Invoke直接抛出的异常,包装由方法本身抛出的异常。

你能想出一个类似的简短但完整的程序来演示这个问题吗?

如果在使用反射调用的方法中发生错误,它应该抛出一个TargetInvocationException来包装(通过.InnerException)原始的。但是,有一些方法可能会导致更多的终端失败,例如围绕winform创建/消息循环的一些方法。

也有可能该方法正在工作,但导致额外的工作发生在另一个线程上,并且正在失败。这将杀死线程,并且您无法捕获它,因为它不在您的线程上。如果您的代码实际上是在工作线程上,那么这种情况尤其可能发生。