多線程應用程序中調用窗體的一點心得

- 中國WEB開發者網絡 (http://www.webasp.net)
-- 技術教程 (http://www.webasp.net/article/)
--- 多線程應用程序中調用窗體的一點心得 (http://www.webasp.net/article/17/16917.htm)
-- 作者:未知
-- 發佈日期: 2005-03-10
昨天自己編寫一個多線程的程序,主要作用是TCP通迅的小程序,裡面使用了多線程的技術,遇到一個有趣的問題:就是在工作線程中我調用了一個窗體,讓它顯示出來。如Form1 f=new Form1();f.show();這種代碼平時一點問題都沒有。但是在工作線程中卻無法調過了。我的FORM1在桌面上動彈不得了。什麼也不響應。有點像假死機的狀態。後來我將Form1 f;這代碼放到主線程裡去實例化,一切都正常了。(估計是工作線程的原因)

經過查閱MSDN才知道:

當程序運行時,我們已經開啟了一個線程,UI 線程. 而平時的一般工作,比如說新開窗口啦,按鈕事件啦,這都是在UI 線程的管轄之下。而如果我們新建一個線程,當這個線程需要調用一個新窗口的時候,不可以直接在這個新線程之下調用,而是需要讓UI 線程去調用新窗口。而新的線程所做的是給UI線程發送一條信息,讓它打開窗口。而做這一步,我們就需要用到Delegate 技術。 如果一個控件的處理程序和操作它的代碼不在同一線程中,則需要使用 控件名.Invoke 方法


代碼片斷如下:

//工作線程的代碼將直接調用FOrm下定義的FormShow方法

ListenerThread()

{

//這是一個自由線程。不能在這裡直接調用一個窗體

FormShow();//OK

}

delegate void FormHandler(DataSet ds);//聲明一個委託

//定義一個方法此方法用來顯示一個窗體

private void FormShow(DataSet ds)
{
if (!this.InvokeRequired) //如果當前線程不是主UI線程,返回true,否則,返回false.
{
frmBills fb = new frmBills();
fb.Show();
fb.Display(ds);
}

else

{
FormHandler fHandler = new FormHandler(this.FormShow); //創建一個新instance指向FormShow.
this.Invoke(fHandler, new object[] {ds}); //啟動delegate
}



webasp.net