轉(zhuǎn)帖|其它|編輯:郝浩|2010-09-20 11:03:58.000|閱讀 830 次
概述:本文將介紹vs2005中解決不能跨線程調(diào)用控件問題,希望對大家有幫助。
# 界面/圖表報(bào)表/文檔/IDE等千款熱門軟控件火熱銷售中 >>
如果代碼是在 VS2003中的話應(yīng)該不會拋出這個異常,只有在使用VS2005的時候,如果你從非創(chuàng)建這個控件的線程中訪問這個控件或者操作這個控件的話就會拋出這個異常。這是微軟為了保證線程安全以及提高代碼的效率所做的改進(jìn).
以前在 VS2003中,我們通常都會忽略這種問題的存在,無限制的使用線程來完成一些工作,但是當(dāng)系統(tǒng)慢慢變大的時候,這種濫用的線程不但沒有提高我們的效率,反而使我們找錯誤的效率以及系統(tǒng)的復(fù)雜度大大的增加了。
微軟的這一改動可以讓我們在使用線程的時候,充分考慮一下線程的安全以及線程的使用規(guī)范,這樣會有益于我們做出健壯的程序。
堅(jiān)決這種跨線程的問題在 VS2005中提供了兩種簡單的方法(我個人當(dāng)前所了解的只有這兩種):
一種是通過設(shè)置 System.Windows.Forms.Control.CheckForIllegalCrossThreadCalls = false;(winform 下)如果在你的程序初始化的時候設(shè)置了這個屬性,而且在你的控件中使用的都是微軟 Framework 類庫中的控件的話,系統(tǒng)就不會再拋出你上面所說的這個錯誤了。當(dāng)然這只是為了將 VS2003的代碼轉(zhuǎn)換到 VS2005下所使用的一種常見的方法。不建議采用。
第二種方法就是微軟建議采用的跨線程調(diào)用的一種通用方法,就是使用代理來實(shí)現(xiàn),就是將你所要操作的代碼放到一個代理種,然后將這個代理交給創(chuàng)建這個控件的線程來執(zhí)行你的代碼。例如:
private void Form1_Load(object sender, EventArgs e)
{
//創(chuàng)建線程需要 System.Threading 命名空間
Thread t1, t2; // 說明為窗體類成員
t1 = new Thread(new ThreadStart(BackgroundProcess));
t1.Start(); //啟動線程t1
}
/// <summary>
/// 定義一個代理
/// </summary>
private delegate void dd();
private void BackgroundProcess()
{
// 將代理實(shí)例化為一個匿名代理
dd = delegate()
{
int i = 1;
while (true)
{
// 向列表框增加一個項(xiàng)目
listBox1.Items.Add("Iterations: " + i.ToString());
i++;
Thread.Sleep(2000); // 指定線程休眠的時間
}
};
listBox1.Invoke(dd);
}
上面這個代碼只是在你的代碼中聲明了一個代理,并且用 VS2005中新加的語法(匿名代理,又名匿名方法。)來實(shí)例話這個代理,將你在線程中要操作的代碼都放到這個匿名的方法中去。然后通過使用控件的 Invoke 方法(也可以使用控件的 BeginInvoke 方法——Invoke 方法是同步的 BeginInvoke 方法是異步的)來調(diào)用這個代理。當(dāng)然在 Invoke 方法中你也可以輸入任何形式的代理。通過這種方式調(diào)用的代碼就不會拋出你出現(xiàn)的那個異常了。
上面這種代理的方式類似于 C++中的回調(diào)函數(shù),你寫出了執(zhí)行的方法,然后通知某個線程由那個線程來調(diào)用你的這個方法,這樣就做到了在固定的線程里執(zhí)行修改線程內(nèi)部組件的方式。這樣就完全達(dá)到線程安全了。
另外,如果你使用的不是.NET 類庫中的控件的話,最好不要使用第一種方式,因?yàn)槟承┑谌娇丶诰€程安全性方面做的不是太好,可能還會拋出一些不可預(yù)料的異常。例如 DevExpress 控件庫一般會拋出對象引用為空的異常。所以建議所有在 VS2005種使用線程操作控件的時候都利用第二種方法來實(shí)現(xiàn),如果嫌麻煩,也可以將這些控件利用繼承的方式在父類里面實(shí)現(xiàn)這些代理方式的修改。
本站文章除注明轉(zhuǎn)載外,均為本站原創(chuàng)或翻譯。歡迎任何形式的轉(zhuǎn)載,但請務(wù)必注明出處、不得修改原文相關(guān)鏈接,如果存在內(nèi)容上的異議請郵件反饋至chenjj@fc6vip.cn
文章轉(zhuǎn)載自:網(wǎng)絡(luò)轉(zhuǎn)載