【技術干貨】在C#的涉及UI的開發中,跨線程直接訪問控件的解決方案
解決方案:
通過委托的方式,實現將當前線程的將要執行的命令,插入到訪問控件的線程中.
經典的解釋:
你想要買東西,然而你沒有足夠的零花錢(沒有足夠的權限),你需要通過你老爸幫你買東西(執行功能代碼)。
你不能直接拿你老爸的錢包去買東西(跨線程),因為這樣子是不合適的。
但你可以告訴你老爸你喜歡這玩具(委托),讓你老爸拿自己的錢包去買東西(讓控件的所在線程執行功能代碼)。
WinForm的UI開發:
可以通過control.InvokeRequired判斷該控件是屬于本線程,如果不屬于本線程,則返回ture。
通過在函數頭對control.InvokeRequired的判斷,能夠將所在函數作為獨立函數調用。
當所訪問控件的線程執行到該委托事件時,由于該控件是在本線程執行。因此,不會創建委托事件,從而執行功能代碼。
MFC的UI開發:
MFC的Invoke相關的API是存在control.Dispatcher中,但不存在InvokeRequired這API。
由于不存在InvokeRequired這API,因此無法判斷是否跨線程調用控件。
不能夠將所在的函數作為獨立函數調用(如上述的實現方式)。
只能通過常規的實現方式實現:
轉載請備注:
通過委托的方式,實現將當前線程的將要執行的命令,插入到訪問控件的線程中.
經典的解釋:
你想要買東西,然而你沒有足夠的零花錢(沒有足夠的權限),你需要通過你老爸幫你買東西(執行功能代碼)。
你不能直接拿你老爸的錢包去買東西(跨線程),因為這樣子是不合適的。
但你可以告訴你老爸你喜歡這玩具(委托),讓你老爸拿自己的錢包去買東西(讓控件的所在線程執行功能代碼)。
實現過程:
a.創建委托函數delegate void MyDele(
);
b.將要執行的功能代碼封裝成獨立函數或Lambda表達式或者匿名方法,添加到委托事件中。
獨立函數:
MyDele my = new MyDele(獨立函數名);
Lambda表達式:
MyDele my =(傳參)=>{要執行的功能代碼;};
匿名方法:
MyDele my = delegate(傳參){要執行的功能代碼;};
c.將委托插入到訪問控件的線程中。
this.BeginInvoke(委托事件名,傳參);
);b.將要執行的功能代碼封裝成獨立函數或Lambda表達式或者匿名方法,添加到委托事件中。
獨立函數:
MyDele my = new MyDele(獨立函數名);
Lambda表達式:
MyDele my =(傳參)=>{要執行的功能代碼;};
匿名方法:
MyDele my = delegate(傳參){要執行的功能代碼;};
c.將委托插入到訪問控件的線程中。
this.BeginInvoke(委托事件名,傳參);
WinForm的UI開發:
可以通過control.InvokeRequired判斷該控件是屬于本線程,如果不屬于本線程,則返回ture。
通過在函數頭對control.InvokeRequired的判斷,能夠將所在函數作為獨立函數調用。
void TestFunction(
)
{
if(control.InvokeRequired)
{
MyDele my = new MyDele(TestFunction);
this.BeginInvoke(my,
);
return;
}
要執行的功能代碼;
}
在跨線程調用控件時,會創建委托事件,將該函數添加到委托事件中,插入到訪問控件的線程中,并且退出該函數。
){
if(control.InvokeRequired)
{
MyDele my = new MyDele(TestFunction);
this.BeginInvoke(my,
);return;
}
要執行的功能代碼;
}
當所訪問控件的線程執行到該委托事件時,由于該控件是在本線程執行。因此,不會創建委托事件,從而執行功能代碼。
MFC的UI開發:
MFC的Invoke相關的API是存在control.Dispatcher中,但不存在InvokeRequired這API。
由于不存在InvokeRequired這API,因此無法判斷是否跨線程調用控件。
不能夠將所在的函數作為獨立函數調用(如上述的實現方式)。
只能通過常規的實現方式實現:
void TestFunction(
)
{
// a.獨立函數:
MyDele my = new MyDele(獨立函數名);
// b.Lambda表達式:
MyDele my =(傳參)=>{要執行的功能代碼;};
//c.匿名方法:
MyDele my = delegate(傳參){要執行的功能代碼;};
this.Dispatcher.BeginInvoke(my,傳參);
}
通過將要執行的功能代碼/函數,添加到委托事件中,再將該委托事件插入到控件所在的線程,讓控件所在的線程執行該功能代碼/函數。
){
// a.獨立函數:
MyDele my = new MyDele(獨立函數名);
// b.Lambda表達式:
MyDele my =(傳參)=>{要執行的功能代碼;};
//c.匿名方法:
MyDele my = delegate(傳參){要執行的功能代碼;};
this.Dispatcher.BeginInvoke(my,傳參);
}
轉載請備注:
**************************************
* 作者: Wurq
* 博客: http://m.shnenglu.com/wurq/
* 日期: 2017/8/16
**************************************
* 作者: Wurq
* 博客: http://m.shnenglu.com/wurq/
* 日期: 2017/8/16
**************************************
posted on 2017-08-16 22:50 Wurq 閱讀(185) 評論(0) 編輯 收藏 引用 所屬分類: 【技術干貨】
