invokeRequired属性和 invoke()方法
zt:?http://www.x2blog.cn/jinhong618/?tid=22389?
問: f (this.InvokeRequired)
??????????? {
??????????????? this.BeginInvoke(new MethodInvoker(LoadGlobalImage));
??????????????? return;
??????????? }
是什么意思
答: c#中禁止跨線程直接訪問控件,InvokeRequired是為了解決這個(gè)問題而產(chǎn)生的
當(dāng) 一個(gè)控件的InvokeRequired屬性值為真時(shí),說明有一個(gè)創(chuàng)建它以外的線程想訪問它,此時(shí)它將會(huì)在內(nèi)部調(diào)用new MethodInvoker(LoadGlobalImage)來完成下面的步驟,這個(gè)做法保證了控件的安全,你可以這樣理解,有人想找你借錢,他可以直 接在你的錢包中拿,這樣太不安全,因此必須讓別人先要告訴你,你再?gòu)淖约旱腻X包把錢拿出來借給別人,這樣就安全了
another:
在設(shè)計(jì)中為了讓界面與邏輯分離,我的做法是使用事件,界面只要響應(yīng)事件來處理界面的顯示就行了。而事件在邏輯處理中可能由不同的線程引發(fā),這些事件的響應(yīng)方法在修改界面中的控件內(nèi)容時(shí)便會(huì)引發(fā)一個(gè)異常。這時(shí)就用到了Control.InvokeRequired 屬性 與Invoke方法。
MSDN中說:
獲取一個(gè)值,該值指示調(diào)用方在對(duì)控件進(jìn)行方法調(diào)用時(shí)是否必須調(diào)用 Invoke 方法,因?yàn)檎{(diào)用方位于創(chuàng)建控件所在的線程以外的線程中。?
如果控件的 Handle 是在與調(diào)用線程不同的線程上創(chuàng)建的(說明您必須通過 Invoke 方法對(duì)控件進(jìn)行調(diào)用),則為 true;否則為 false。
Windows 窗體中的控件被綁定到特定的線程,不具備線程安全性?。因此,如果從另一個(gè)線程調(diào)用控件的方法,那么必須使用控件的一個(gè) Invoke 方法來將調(diào)用封送到適當(dāng)?shù)木€程。該屬性可用于確定是否必須調(diào)用 Invoke 方法,當(dāng)不知道什么線程擁有控件時(shí)這很有用。
下面來說下這個(gè)的用法(我的一般做法):
首先定義一個(gè)委托,與這個(gè)事件處理函數(shù)的簽名一樣委托,當(dāng)然直接使用該事件的委托也是可以的,如:
然后就是判斷這個(gè)屬性的值來決定是否要調(diào)用Invoke函數(shù):
?void??m_comm_MessageEvent(?string??msg)????{
?????if?(txtMessage.InvokeRequired)
?????{
?????InvokeCallbackmsgCallback??=???new??InvokeCallback(m_comm_MessageEvent);
?????txtMessage.Invoke(msgCallback,??new???object?[]??{?msg?}?);
????}?
?????else?
?????{
?????txtMessage.Text??=??msg;
????}?
???}
說明:這個(gè)函數(shù)就是事件處理函數(shù),txtMessage是一個(gè)文本框。
這樣就做到了窗體中控件的線程安全性。
?
------------------
InvokeRequired 當(dāng)前線程不是創(chuàng)建控件的線程時(shí)為true
比如你可以自己開一個(gè)Thread,或使用Timer的事件來訪問窗體上的控件的時(shí)候,在線程中窗體的這個(gè)屬性就是True的。
簡(jiǎn)單的說,如果有兩個(gè)線程,Thread A和Thread B,并且有一個(gè)Control c,是在Thread A里面new的。
那么在Thread A里面運(yùn)行的任何方法調(diào)用c.InvokeRequired都會(huì)返回false。
相反,如果在Thread B里面運(yùn)行的任何方法調(diào)用c.InvokeRequired都會(huì)返回true。
是否是UI線程與結(jié)果無關(guān)。(通常Control所在的線程是UI線程,但是可以有例外)
也可以認(rèn)為,在new Control()的時(shí)候,control用一個(gè)變量記錄下了當(dāng)前線程,在調(diào)用InvokeRequired時(shí),返回當(dāng)前線程是否不等于new的時(shí)候記錄下來的那個(gè)線程。
--------------------
我理解:如果InvokeRequired==true表示其它線程需要訪問控件,那么調(diào)用invoke來轉(zhuǎn)給控件owner處理。
轉(zhuǎn)載于:https://www.cnblogs.com/zzh1236/archive/2012/08/19/2646218.html
總結(jié)
以上是生活随笔為你收集整理的invokeRequired属性和 invoke()方法的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 函数要多小才够好——谈小函数之道
- 下一篇: 每日英语:Relationship Re