解决异常:公共语言运行时检测到无效的程序

  我碰到这个问题比较奇怪,在开发OrayTalk的组织结构功能时,其中的一个方法(基于.NET 2.0)在win7、win2003下运行没有问题,在winxp下运行就抛异常:“公共语言运行时检测到无效的程序”,对应英文为:common language runtime detected an invalid program.

  抛异常的方法代码摘抄如下:

    private Control control = ...;
    public void ActionOnUI<T1>(bool showMessageBoxOnException, bool beginInvoke,  CbGeneric<T1> method, params object[] args)
    {
        if (this.control.InvokeRequired)
        {
            if (beginInvoke)
            {
                this.control.BeginInvoke(new CbGeneric<bool, bool, CbGeneric<T1>, object[]>(this.ActionOnUI), showMessageBoxOnException, beginInvoke, method, args);
            }
            else
            {
                this.control.Invoke(new CbGeneric<bool, bool, CbGeneric<T1>, object[]>(this.ActionOnUI), showMessageBoxOnException, beginInvoke, method, args);
            }
        }
        else
        {
            try
            {
                method((T1)args[0]);
            }
            catch (Exception ee)
            {                if (showMessageBoxOnException)
                {
                    MessageBox.Show(ee.Message);
                }
            }
        }
    }

    方法的目的是对UI调用转发做一个封装,让使用者更方便的将调用转发到UI线程。

    但是,这个方法在执行时,异常在xp下发生了:

     Common Language Runtime detected an invalid program.

at ESBasic.Helpers.UiSafeInvoker.ActionOnUI[T1](Boolean showMessageBoxOnException, Boolean beginInvoke, CbGeneric`1 method, Object[] args)

     我在网上搜了一些相关问题的解答,比较靠谱的一点是这样说的:

    “这种错误非常少见,是一个编译器错误,通常产生在将C#等托管语言生成为MSIL时候出的错,没有什么好的解决办法,现在可行的方法好像就是修改现在的程序结构,这样根据新的结构生成新的MSIL时不会出错就基本可以避免这个问题。”

    根据这个提示,我对方法的代码进行了各种修改尝试,最后终于得到了一种在xp下也不抛异常的结构,粘贴如下:

    private Control control = ...;
    public void ActionOnUI<T1>(bool showMessageBoxOnException, bool beginInvoke, CbGeneric<T1> method, T1 args)
    {
        if (this.control.InvokeRequired)
        {
            if (beginInvoke)
            {
                this.control.BeginInvoke(new CbGeneric<bool, CbGeneric<T1>, T1>(this.Do_ActionOnUI<T1>), showMessageBoxOnException, method, args);
                return;
            }
            this.control.Invoke(new CbGeneric<bool, CbGeneric<T1>, T1>(this.Do_ActionOnUI<T1>), showMessageBoxOnException, method, args);
            return;
        }

        this.Do_ActionOnUI<T1>(showMessageBoxOnException, method, args);
    }

    private void Do_ActionOnUI<T1>(bool showMessageBoxOnException, CbGeneric<T1> method, T1 args)
    {
        try
        {
            method(args);
        }
        catch (Exception ee)
        {            if (showMessageBoxOnException)
            {
                MessageBox.Show(ee.Message);
            }
        }
    } 

  总结起来,改变的几点如下:

(1)将真正执行的部分重构为一个方法Do_ActionOnUI,然后,转发调用Invoke都指向这个方法。

(2)Invoke转发调用时,为指向的方法加上泛型参数,避免编译器自动去匹配。

(3)将弱类型的参数object[]修改为强类型的参数T1。

  好吧,问题总算是解决了,好好折腾了一番啊~~

时间: 2024-10-27 09:25:44

解决异常:公共语言运行时检测到无效的程序的相关文章

安装Visual Studio2015后,使用VS2013开发的项目,在IIS访问都提示“公共语言运行时检测到无效的程序”的解决办法

1.安装VS2015后,.NET Framework4.6会替换掉 C:\Windows\Microsoft.NET\Framework64\v4.0.30319 (如果使用的是windows7 64位版本)的文件,导致VS2013开发的项目在IIS中浏览都会出现如下错误: 2.折腾了很久,翻阅大量的搜索资料也无法解决,最后在IIS中设置应用池的“启用32位应用程序” 为true后,再打开站点,一切恢复正常了 留个几号,以备查阅!

JVM【第七回】:【OutOfMemoryError异常之运行时常量池溢出】

如果要向运行时常量池中添加内容,最简单的做法就是使用String.intern()这个Native方法.该方法的作用是:如果池中已经包含一个等于此String对象的字符串,则返回代表池中这个字符串的String对象:否则将此String对象包含的字符串添加到常量池中,并且返回此String对象的引用.由于常量池分配在方法区内,我们可以通过-XX:PermSize和-XX:MaxPermSize限制方法区的大小,从而间接限制其中产量池的容量:代码如下: package oom; import ja

编译时异常与运行时异常的区别

Java异常类层次结构图 Java异常类层次结构图 运行时异常:都是RuntimeException类及其子类异常,如NullPointerException(空指针异常).IndexOutOfBoundsException(下标越界异常)等,这些异常是不检查异常,程序中可以选择捕获处理,也可以不处理.这些异常一般是由程序逻辑错误引起的,程序应该从逻辑角度尽可能避免这类异常的发生. 运行时异常的特点是Java编译器不会检查它,也就是说,当程序中可能出现这类异常,即使没有用try-catch语句捕

如何解决android studio 运行时中文乱码的问题

相信很多朋友都会遇到android studio 在MAC OS中运行的时候中文乱码.而在代码编辑的时候正常.经过几天的不断寻找解决办法,终于解决了 比如: Toast.makeText(MainActivity.this,"我爱你", Toast.LENGTH_LONG).show(); 运行的时候在模拟器里就是乱码. 解决办法网上很多,但是都不能解决运行时乱码的问题.所以这个问题苦恼了几天. 我们在工程里的build.grandle 文件中添加一段代码即可 tasks.withTy

java中的一般异常与运行时异常

Java提供了两类主要的异常:runtime exception和checked exception.checked 异常也就是我们经常遇到的IO异常,以及SQL异常都是这种异常.对于这种异常,JAVA编译器强制要求我们必需对出现的这些异常进行catch.所以,面对这种异常不管我们是否愿意,只能自己去写一大堆catch块去处理可能的异常. 但是另外一种异常:runtime exception,也称运行时异常,我们可以不处理.当出现这样的异常时,总是由虚拟机接管.比如:我们从来没有人去处理过Nul

java 检查抛出的异常是否是要捕获的检查性异常或运行时异常或错误

/** * Return whether the given throwable is a checked exception: * that is, neither a RuntimeException nor an Error. * @param ex the throwable to check * @return whether the throwable is a checked exception * @see java.lang.Exception * @see java.lang

C#中CLR(公共语言运行时)与IL(中间代码)

.net平台中的CLR 首先要说明的是,.NET平台与C#不是一回事 它是C#,VB.net等程序运行的平台. CLR是公共语言运行时,是 .NET Framework的重要组成部分.它提供了内存管理.线程管理和异常处理等服务,而且还负责对代码实施严格的类型安全检查,保证了代码的正确性. 事实上,类型安全(Type Checker).垃圾回收(Garbage Collector).异常处理(Exception Manager).向下兼容(COM Marshaler)等很多C#中的特性都是由CLR

Unity运行时检测Altas使用情况

UI贴图在游戏中内存大小中占的分量非常非常大,尤其对于前期对UI没有规划的项目,无论是包量还是内存大小都是需要花费很多时间去优化.如果涉及到战斗场景和逻辑场景的情况下,常用的做法就是把两个场景使用的atlas严格的分离开,这样可以减少运行时内存,特别是在战斗中,内存增加的比较厉害.OK,如果项目前期这方面的事情考虑比较周全.规则比较详细.执行也比较到位,后期可能就做这个事情就比较简答.那如果出现战斗中引用不该有的atlas怎么办?UI太多的情况下,逐个排除太麻烦,尤其是不在UI中,只是静态引进的

对公共语言运行时的学习笔记

图文讲解.NET CLR是什么 - 51CTO.COMhttp://developer.51cto.com/art/200910/158022.htm 通用语言运行时(CommonLanguageRuntiome,CLR)最早被称为下一代Windows服务运行时(NGWS Runtime).它是直接建立在操作系统上的一个虚拟环境,主要的任务是管理代码的运行.CLR现在支持几十种现代的编程语言为它编写代码,然后以一种中间语言(Intermediate Langeoage,IL)代码的形成被执行.并