首页 > 代码库 > 解决异常:公共语言运行时检测到无效的程序

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

  我碰到这个问题比较奇怪,在开发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。

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

 

 

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