C#中跨線程訪問控件的實現方法
一、簡述
C#中不允許跨線程直接訪問界面控件,即一個線程中如主線程創(chuàng)建的控件不允許被其他線程例如子線程直接訪問,如果直接訪問或設置屬性則會爆出“調用線程無法訪問此對象,因為另一個線程擁有該對象”等類似錯誤。
在一個線程中設置其他線程所有的控件屬性通常有兩種方法,一是設置System.Windows.Forms.Control的CheckForIllegalCrossThreadCalls屬性值為false,表示不對錯誤線程的調用進行捕捉,這種方法只對winforms界面框架有效,在WPF中無法設置該屬性,只能使用第二種方法。
第二種方法是通過委托來實現控件屬性設置,需要通過Invoke或BeginInvoke來實現,Invoke表示同步,BeginInvoke表示異步,下面列舉了在winforms中和WPF兩種界面框架中跨線程訪問控件的代碼示例。
二、Winforms中跨線程訪問控件
一般的委托方法示例代碼如下:
delegate void delegateSetText(string str);//定義一個委托
private void SetText(string str)
{
if (InvokeRequired)//判斷是否是被其他線程調用
{
delegateSetText delegatesetText01 = new delegateSetText(SetText);
Invoke(delegatesetText01, new object [] {str});
return;
}
textBox01.Text = str;
}
也可以采用匿名代理的方式,示例代碼如下:
delegate void delegateSetText(string str);//定義一個委托
private void SetText(string str)
{
delegateSetText delegatesetText01 = delegate(string str01)
{
textBox01.Text = str01;
}
Invoke(delegatesetText01, new object [] {str});
}
三、WPF中跨線程訪問控件
在WPF中跨線程訪問控件需要使用Dispatcher。Dispatcher是WPF中的線程調度管理器,用在子線程刷新主線程(UI線程)(比如綁定的時候,屬性更新的時候),在子線程里面起一個dispatcher,將工作項目調度到 UI 線程,讓主線程調度刷新UI的代碼。示例代碼如下:
private void SetText(string str)
{
if (!Dispatcher.CheckAccess())//判斷是否是被其他線程調用
{
Dispatcher.Invoke(() => SetText(str));
return;
}
textBox01.Text = str;
}
【注】
避免”在創(chuàng)建窗口句柄之前,不能在控件上調用 Invoke 或 BeginInvoke。“錯誤。
一個Form窗體必須完全創(chuàng)建完成,才能調用它自身或它上面控件的Invoke或BeginInvoke。
經測試,窗體的構造函數內的InitializeComponent()的執(zhí)行完成時,窗體并未創(chuàng)建完成;窗體的構造函數執(zhí)行完成時,窗體也并未創(chuàng)建完成;
在form.show()后,窗體是已經創(chuàng)建完成了。
另外,可以在調用Invoke()前,判斷一下 if (form.Created),以避免此處異常中斷。
最后
到此這篇關于C#中跨線程訪問控件的方法的文章就介紹到這了,更多相關C#跨線程訪問控件內容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!

