解決異常:公共語言運行時檢測到無效的程序

  我碰到這個問題比較奇怪,我寫的一個方法(基於.NET 2.0)在win七、win2003下運行沒有問題,在winxp下運行就拋異常:「公共語言運行時檢測到無效的程序」,對應英文爲:common language runtime detected an invalid program.ui

  拋異常的方法代碼摘抄以下:this

    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線程。spa

    可是,這個方法在執行時,異常在xp下發生了:線程

     Common Language Runtime detected an invalid program. code

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

     我在網上搜了一些相關問題的解答,比較靠譜的一點是這樣說的:編譯器

    「這種錯誤很是少見,是一個編譯器錯誤,一般產生在將C#等託管語言生成爲MSIL時候出的錯,沒有什麼好的解決辦法,如今可行的方法好像就是修改如今的程序結構,這樣根據新的結構生成新的MSIL時不會出錯就基本能夠避免這個問題。」io

    根據這個提示,我對方法的代碼進行了各類修改嘗試,最後終於獲得了一種在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);
            }
        }
    } 

  總結起來,改變的幾點以下:class

(1)將真正執行的部分重構爲一個方法Do_ActionOnUI,而後,轉發調用Invoke都指向這個方法。

(2)Invoke轉發調用時,爲指向的方法加上泛型參數,避免編譯器自動去匹配。

(3)將弱類型的參數object[]修改成強類型的參數T1。

  好吧,如今問題總算是解決了,好好折騰了一番啊~~

相關文章
相關標籤/搜索