C#中跨線程訪問控件的實(shí)現(xiàn)方法
一、簡(jiǎn)述
C#中不允許跨線程直接訪問界面控件,即一個(gè)線程中如主線程創(chuàng)建的控件不允許被其他線程例如子線程直接訪問,如果直接訪問或設(shè)置屬性則會(huì)爆出“調(diào)用線程無(wú)法訪問此對(duì)象,因?yàn)榱硪粋€(gè)線程擁有該對(duì)象”等類似錯(cuò)誤。
在一個(gè)線程中設(shè)置其他線程所有的控件屬性通常有兩種方法,一是設(shè)置System.Windows.Forms.Control的CheckForIllegalCrossThreadCalls屬性值為false,表示不對(duì)錯(cuò)誤線程的調(diào)用進(jìn)行捕捉,這種方法只對(duì)winforms界面框架有效,在WPF中無(wú)法設(shè)置該屬性,只能使用第二種方法。
第二種方法是通過委托來(lái)實(shí)現(xiàn)控件屬性設(shè)置,需要通過Invoke或BeginInvoke來(lái)實(shí)現(xiàn),Invoke表示同步,BeginInvoke表示異步,下面列舉了在winforms中和WPF兩種界面框架中跨線程訪問控件的代碼示例。
二、Winforms中跨線程訪問控件
一般的委托方法示例代碼如下:
delegate void delegateSetText(string str);//定義一個(gè)委托
private void SetText(string str)
{
if (InvokeRequired)//判斷是否是被其他線程調(diào)用
{
delegateSetText delegatesetText01 = new delegateSetText(SetText);
Invoke(delegatesetText01, new object [] {str});
return;
}
textBox01.Text = str;
}
也可以采用匿名代理的方式,示例代碼如下:
delegate void delegateSetText(string str);//定義一個(gè)委托
private void SetText(string str)
{
delegateSetText delegatesetText01 = delegate(string str01)
{
textBox01.Text = str01;
}
Invoke(delegatesetText01, new object [] {str});
}
三、WPF中跨線程訪問控件
在WPF中跨線程訪問控件需要使用Dispatcher。Dispatcher是WPF中的線程調(diào)度管理器,用在子線程刷新主線程(UI線程)(比如綁定的時(shí)候,屬性更新的時(shí)候),在子線程里面起一個(gè)dispatcher,將工作項(xiàng)目調(diào)度到 UI 線程,讓主線程調(diào)度刷新UI的代碼。示例代碼如下:
private void SetText(string str)
{
if (!Dispatcher.CheckAccess())//判斷是否是被其他線程調(diào)用
{
Dispatcher.Invoke(() => SetText(str));
return;
}
textBox01.Text = str;
}
【注】
避免”在創(chuàng)建窗口句柄之前,不能在控件上調(diào)用 Invoke 或 BeginInvoke。“錯(cuò)誤。
一個(gè)Form窗體必須完全創(chuàng)建完成,才能調(diào)用它自身或它上面控件的Invoke或BeginInvoke。
經(jīng)測(cè)試,窗體的構(gòu)造函數(shù)內(nèi)的InitializeComponent()的執(zhí)行完成時(shí),窗體并未創(chuàng)建完成;窗體的構(gòu)造函數(shù)執(zhí)行完成時(shí),窗體也并未創(chuàng)建完成;
在form.show()后,窗體是已經(jīng)創(chuàng)建完成了。
另外,可以在調(diào)用Invoke()前,判斷一下 if (form.Created),以避免此處異常中斷。
最后
到此這篇關(guān)于C#中跨線程訪問控件的方法的文章就介紹到這了,更多相關(guān)C#跨線程訪問控件內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
oledb連接access數(shù)據(jù)庫(kù)示例
本文為大家介紹一個(gè)oledb連接access數(shù)據(jù)庫(kù)的示例,代碼很簡(jiǎn)單,可以直接使用2014-01-01
C#對(duì)文件進(jìn)行批量重命名或者對(duì)某單個(gè)文件進(jìn)行改名的示例代碼
這篇文章主要介紹了C#對(duì)文件進(jìn)行批量重命名或者對(duì)某個(gè)單獨(dú)的文件進(jìn)行改名的實(shí)現(xiàn)方法,文中有相關(guān)的代碼示例供大家參考,具有一定的參考價(jià)值,需要的朋友可以參考下2024-05-05
Unity實(shí)現(xiàn)簡(jiǎn)單虛擬搖桿
這篇文章主要為大家詳細(xì)介紹了Unity實(shí)現(xiàn)簡(jiǎn)單虛擬搖桿,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2020-04-04

