在建立視窗控制代碼之前,不能在控制項上調用 Invoke 或 BeginInvoke

來源:互聯網
上載者:User

今天關閉一個表單,報出這樣的一個錯誤"在建立視窗控制代碼之前,不能在控制項上調用 Invoke 或 BeginInvoke。",這個不用多想,肯定是那個地方沒有釋放掉。
既然碰到這個問題,先不說問題本身,來說說其他的一些事情。
winform最常見的是datagridview這個控制項,不管重寫還是怎麼,很多資料的操作都是用datagridview來展示的,因此,它的非同步呼叫也算是比較多的一類了。
比如:
1 從資料庫中讀取大量資料(所謂的分頁讀取不在這個範疇)
2 操作datagridview,然後一段時間後改變或者填充dtagridview
3 datagridview本身的一些效果,比如旋轉的延時等待,或者其他
不用非同步肯定會出現死機的情況,用了非同步可能也要注意一些情況

一個簡單的例子:
一個showdialog表單裡有個一個datagridview,我用非同步讀取資料,但是沒讀完,我關了表單,這時候,資料讀完了,要執行
datagridview.source=??
這個時候,會出錯,可能不是"在建立視窗控制代碼之前,不能在控制項上調用 Invoke 或 BeginInvoke。"這個錯誤,而是"資源已經釋放之類的",那咱們看看下面的幾個方法。
1 this.components 這個屬性

 /// <summary>        /// Required designer variable.        /// </summary>        private System.ComponentModel.IContainer components = null;

每一個Designer.cs裡都有一個這個東西,IContainer介面相當於是一個容器,一個頁面全部的東西都會放在裡面,你拖一個button或者label都會放在裡面,筆者覺得,這個其實就是wpf的一個容器的概念,你可以從root尋找到每一個控制項,而IContainer也可以找到你想要的控制項,Active啟用或者不啟用會用到這個。
表單釋放,components 也會釋放

 /// <summary>        /// Clean up any resources being used.        /// </summary>        /// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>        protected override void Dispose(bool disposing)        {            if (disposing && (components != null))            {                components.Dispose();            }            base.Dispose(disposing);        }

這個方法會釋放,所以可以當做判斷表單是否釋放的一個依據,但是筆者不推舉

2 this.IsDisposed
這個是判斷是否已經釋放了,用這個判斷比 components 要好一些,具體的原因是components在表單關閉後可能沒有釋放,而this.IsDisposed表單必然已經釋放了,當表單是MID模式的時候,由於線程或其他原因,表單的關閉可能不會釋放

3 IsHandleCreated
控制代碼是否建立
當子空間控制代碼建立了,而它的parent的控制代碼由於其他原因沒有建立或者已經釋放了,則也會出現其他問題,所以這個可以通過Parent.IsHandleCereated來盤點父控制代碼是否存在或者已經建立

上面幾個方法可以組合用,筆者判斷的時候差不多用後兩個
現在說說這兩個Invoke 和 BeginInvoke
Control.Invoke:在擁有此控制項的線程上先進先出順序執行委託
Control.BeginInvoke:在擁有此控制項線程上非同步執行委託,也就是可能並非順序執行,這個有點熟悉,貌似說過了

最後說說解決方案:
在Invoke(....)之前加上1 this.components==null 2 this.IsDisposed 3 IsHandleCreated 來return 不執行invoke就可以,當然只是我針對自己遇到的解決的,可能並不適合其他的,但是總不會脫離其中

 set            {                if (IsDisposed ||!this.Parent.IsHandleCreated) return;                this.Invoke((System.Action)delegate()                {                                  });            }

 

這是我的判斷

 

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.