在建立窗口句柄以前,不能在控件上調用 Invoke 或 BeginInvoke。

本文轉載:http://blog.csdn.net/playing9c/article/details/7471918html

             http://blog.csdn.net/beelinkerlidejun/article/details/4772491多線程

             http://www.cnblogs.com/fish124423/archive/2012/10/16/2726543.html異步

C#窗體的多線程一直是個難題,老是要出現奇奇怪怪的錯誤。今天開發alexSEO軟件時,出現了在建立窗口句柄以前,不能在控件上調用 Invoke 或 BeginInvoke。主要出現問題代碼以下:ide

   protected override void OnLoad(EventArgs e)
        {
            base.OnLoad(e);
            txtRFID_Click(null, null);

        }
View Code

 

   private void txtRFID_Click(object sender, EventArgs e)
        {
            Thread thread = new Thread(() =>
            {
                if (this.IsHandleCreated)
                    this.BeginInvoke(new MethodInvoker(() =>
                   {
                       this.txtRFID.Enabled = false;
                   }));

                int iRet = -1;
                string strTid = "";
                iRet = WriteCardHelper.Instance.ReadTID(ref strTid); //讀取耗時的代碼;
//注意:耗時的代碼不能放在 this.BeginInvoke(new MethodInvoker(() => 耗時代碼 })); //中執行;不然沒有產生異步的效果。
//BeginInvoke中只能放置操做控件的代碼。BeginInvoke將子線程線程經過委託拋向UI主線程 。
if (this.IsHandleCreated) this.BeginInvoke(new MethodInvoker(() => { this.errorProvider.SetError(this.txtRFID, ""); if (0 == iRet) { WriteCardHelper.Instance.SetAlarm(); this.txtRFID.Text = strTid; this.txtRFID.BackColor = Color.White; this.errorProvider.SetError(this.txtRFID, ""); } else { this.txtRFID.Text = ""; this.txtRFID.BackColor = Color.Pink; } this.txtGasBottleNo.Focus(); this.txtRFID.Enabled = true; })); }); thread.IsBackground = true; thread.Start(); }

 

客戶端:(實現異步打開窗體,該窗體加載的時候會讀取設備的數據,但會很耗時,爲了防止窗體加載時候因爲耗時的代碼,致使不能及時的顯示出來)this

 frmGasBottlesInstall frmInstall = new frmGasBottlesInstall(gasBottlesID);
 frmInstall.ShowDialog();  //異步打開窗口。

 

當調試運行中忽然關閉軟件時,labb.Invoke(labchange);語句就出先了「在建立窗口句柄以前,不能在控件上調用 Invoke 或 BeginInvoke。」錯誤。想了一通出現這種狀況應該有兩種可能。第一種應該是界面還來不及響應Invoke,第二種是界面線程已經結束,因此響應不了。最後解決辦法是在labb.Invoke(labchange);前加一個if(labb.IsHandleCreated)判斷就能夠了。spa

相關文章
相關標籤/搜索