欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

无法捕获的异常:MissingMethodException

程序员文章站 2022-05-01 18:18:55
今天一个同事发布站点,一直出现一些稀奇古怪的问题,各种各样的异常都有,根据这些异常去排查代码,都完全正常,很让人郁闷,因为代码里可能出异常的地方都记录了程序日志,所以他一直没去排查...

今天一个同事发布站点,一直出现一些稀奇古怪的问题,各种各样的异常都有,根据这些异常去排查代码,都完全正常,很让人郁闷,因为代码里可能出异常的地方都记录了程序日志,所以他一直没去排查系统里的“应用程序日志”,只是在查程序,

后面找到我,我第一时间去看系统日志里的“应用程序日志”,果然有一堆的异常:
异常信息:
   异常类型: MissingMethodException
   异常消息: 找不到方法:“nameSp.abc.xxx()”。

然后就清楚了,这个xxx方法是nameSp.dll里新增的一个方法,再确认一下这个dll,果然是没发布最新dll,用的还是旧的dll,把nameSp.dll发布后,问题排除。

这时,同事还有一个问题,他说:我的代码是类似这样的:
try{
    nameSp.abc.xxx();
}catch(Exception exp){
    // 记录日志
}

为什么上面的代码没有记录日志呢?

我也晕了一下,后面写一个测试程序:
文件1:
class Program
{
    static void Main(string[] args)
    {
        try
        {
            new MethodNoTest().Run();
        }
        catch(Exception exp)
        {
            Console.WriteLine("外部出错:" + exp);
        }
    }
}

文件2:
public class MethodNoTest
{
    public void Run()
    {
        Console.WriteLine("开始");
        try
        {
            nameSp.abc.xxx();
        }
        catch (Exception exp)
        {
            Console.WriteLine("内部出错:" + exp);
        }
        Console.WriteLine("完成");
    }
    public void aa(){
        Console.WriteLine("abc");
    }

}

引用新dll编译成功后,再把旧dll拷贝到exe目录下,执行结果是:
外部出错:System.MissingMethodException:找不到方法:“void nameSp.abc.xxx()”

很奇怪吧,为什么连“开始”和“完成”都没有输出呢?

答案是编译完成的dll,只是il代码,并不是真正的机器码,.net程序在运行前还要把il代码编译转换为机器码执行,上面程序步骤:
1、Program类编译正常,执行到new MethodNoTest().Run();
2、发现MethodNoTest的Run方法未编译为机器码,开始编译,发现方法里引用的abc类没有定义xxx这个方法,就直接抛出异常,所以Run这个方法里的任何一句代码都没有执行,更不要说里面的try能起作用了。

但是MethodNoTest类的另外一个方法aa,能正常调用和执行