本文轉載: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); }
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