資源描述:
《c#窗體中invoke和begininvoke方法詳解》由會(huì)員上傳分享,免費(fèi)在線閱讀,更多相關(guān)內(nèi)容在行業(yè)資料-天天文庫(kù)。
1、在Invoke或者BeginInvoke的使用中無(wú)一例外地使用了委托Delegate,至于委托的本質(zhì)請(qǐng)參考我的另一隨筆:對(duì).net事件的看法。?一、為什么Control類(lèi)提供了Invoke和BeginInvoke機(jī)制?關(guān)于這個(gè)問(wèn)題的最主要的原因已經(jīng)是dotnet程序員眾所周知的,我在此費(fèi)點(diǎn)筆墨再次記錄到自己的日志,以便日后提醒一下自己。1、windows程序消息機(jī)制WindowsGUI程序是基于消息機(jī)制的,有個(gè)主線程維護(hù)著一個(gè)消息泵。這個(gè)消息泵讓windows程序生生不息。?????????????????????????????????????????????????WindowsGUI程序
2、的消息循環(huán)??Windows程序有個(gè)消息隊(duì)列,窗體上的所有消息是這個(gè)隊(duì)列里面消息的最主要來(lái)源。這里的while循環(huán)使用了GetMessage()這個(gè)方法,這是個(gè)阻塞方法,也就是隊(duì)列為空時(shí)方法就會(huì)被阻塞,從而這個(gè)while循環(huán)停止運(yùn)動(dòng),這避免了一個(gè)程序把cpu無(wú)緣無(wú)故地耗盡,讓其它程序難以得到響應(yīng)。當(dāng)然在某些需要cpu最大限度運(yùn)動(dòng)的程序里面就可以使用另外的方法,例如某些3d游戲或者及時(shí)戰(zhàn)略游戲中,一般會(huì)使用PeekMessage()這個(gè)方法,它不會(huì)被windows阻塞,從而保證整個(gè)游戲的流暢和比較高的幀速。這個(gè)主線程維護(hù)著整個(gè)窗體以及上面的子控件。當(dāng)它得到一個(gè)消息,就會(huì)調(diào)用DispatchMes
3、sage方法派遣消息,這會(huì)引起對(duì)窗體上的窗口過(guò)程的調(diào)用。窗口過(guò)程里面當(dāng)然是程序員提供的窗體數(shù)據(jù)更新代碼和其它代碼。2、dotnet里面的消息循環(huán)publicstaticvoidMain(string[]args){??Formf=newForm();??Application.Run(f);}Dotnet窗體程序封裝了上述的while循環(huán),這個(gè)循環(huán)就是通過(guò)Application.Run方法啟動(dòng)的。3、線程外操作GUI控件的問(wèn)題如果從另外一個(gè)線程操作windows窗體上的控件,就會(huì)和主線程產(chǎn)生競(jìng)爭(zhēng),造成不可預(yù)料的結(jié)果,甚至死鎖。因此windowsGUI編程有一個(gè)規(guī)則,就是只能通過(guò)創(chuàng)建控件的線程來(lái)
4、操作控件的數(shù)據(jù),否則就可能產(chǎn)生不可預(yù)料的結(jié)果。因此,dotnet里面,為了方便地解決這些問(wèn)題,Control類(lèi)實(shí)現(xiàn)了ISynchronizeInvoke接口,提供了Invoke和BeginInvoke方法來(lái)提供讓其它線程更新GUI界面控件的機(jī)制。publicinterfaceISynchronizeInvoke{???????[HostProtection(SecurityAction.LinkDemand,Synchronization=true,ExternalThreading=true)]???????IAsyncResultBeginInvoke(Delegatemethod,obj
5、ect[]args);???????objectEndInvoke(IAsyncResultresult);???????objectInvoke(Delegatemethod,object[]args);???????boolInvokeRequired{get;}}}如果從線程外操作windows窗體控件,那么就需要使用Invoke或者BeginInvoke方法,通過(guò)一個(gè)委托把調(diào)用封送到控件所屬的線程上執(zhí)行。二、消息機(jī)制---線程間和進(jìn)程間通信機(jī)制1、window消息發(fā)送Windows消息機(jī)制是windows平臺(tái)上的線程或者進(jìn)程間通信機(jī)制之一。Windows消息值其實(shí)就是定義的一個(gè)數(shù)據(jù)結(jié)構(gòu)
6、,最重要的是消息的類(lèi)型,它就是一個(gè)整數(shù);然后就是消息的參數(shù)。消息的參數(shù)可以表示很多東西。Windows提供了一些api用來(lái)向一個(gè)線程的消息隊(duì)列發(fā)送消息。因此,一個(gè)線程可以向另一個(gè)線程的消息隊(duì)列發(fā)送消息從而告訴對(duì)方做什么,這樣就完成了線程間的通信。有些api發(fā)送消息需要一個(gè)窗口句柄,這種函數(shù)可以把消息發(fā)送到指定窗口的主線程消息隊(duì)列;而有些則可以直接通過(guò)線程句柄,把消息發(fā)送到該線程消息隊(duì)列中。????????????????????????????????????????????????????用消息機(jī)制通信?SendMessage是windowsapi,用來(lái)把一個(gè)消息發(fā)送到一個(gè)窗口的消息隊(duì)列。這
7、個(gè)方法是個(gè)阻塞方法,也就是操作系統(tǒng)會(huì)確保消息的確發(fā)送到目的消息隊(duì)列,并且該消息被處理完畢以后,該函數(shù)才返回。返回之前,調(diào)用者將會(huì)被暫時(shí)阻塞。PostMessage也是一個(gè)用來(lái)發(fā)送消息到窗口消息隊(duì)列的api函數(shù),但這個(gè)方法是非阻塞的。也就是它會(huì)馬上返回,而不管消息是否真的發(fā)送到目的地,也就是調(diào)用者不會(huì)被阻塞。2、InvokeandBeginInvoke????????????????????????