程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> .NET網頁編程 >> C# >> C#入門知識 >> C#窗體中Invoke和BeginInvoke方法詳解,

C#窗體中Invoke和BeginInvoke方法詳解,

編輯:C#入門知識

C#窗體中Invoke和BeginInvoke方法詳解,


在

Invoke

或者

BeginInvoke

的使用中無一例外地使用了委托

Delegate

,至於委托的本

質請

參考

我的另一隨筆:

對

.net

事件的看法

。

 

  

 

一、

為

什

麼

Control

類

提供了

Invoke

和

BeginInvoke

機制?

 

關

於

這

個

問題

的最主要的原因已

經

是

dotnet

程序

員

眾所周知的,我在此

費

點筆墨再次

記錄

到自己

的日志,以便日後提醒一下自己。

 

1

、

windows

程序消息機制

 

Windows 

GUI

程序是基於消息機制的,有個主

線

程

維護

著一個消息

泵

。

這

個消息

泵讓

windows

程序生生不息。

 

 

 

                                                  

Windows GUI

程序的消息循

環

 

 

  

 

  

Windows

程序有個消息

隊

列,

窗體上的所有消息是

這

個

隊

列裡面消息的最主要來源。

這

裡的

while

循

環

使用了

GetMessage

()

這

個方法,

這

是個阻塞方法,也就是

隊

列

為

空

時

方法就會被阻塞,從

而

這

個

while

循

環

停止運

動

,

這

避免了一個程序把

cpu

無

緣

無故地耗盡,

讓

其它程序

難

以得到響

應

。當然在某些需要

cpu

最大限度運

動

的程序裡面就可以使用另外的方法,

例如某些

3d

游

戲

或者

及

時戰

略游

戲

中,一般會使用

PeekMessage

()

這

個方法,它不會被

windows

阻塞,從而保

證

整

個游

戲

的流

暢

和比

較

高的

幀

速。

 

這

個主

線

程

維護

著整個窗體以及上面的子控件。當它得到一個消息,就會

調

用

DispatchMessage

方法派遣消息,

這

會引起

對

窗體上的窗口

過

程的

調

用。

窗口

過

程裡面當然是程序

員

提供的窗體數據

更新代

碼

和其它代

碼

。

 

2

、

dotnet

裡面的消息循

環

 

public static void Main(string[] args) 

{ 

   

Form f = new Form(); 

   

Application.Run(f); 

} 

Dotnet

窗體程序封裝了上述的

while

循

環

,

這

個循

環

就是通

過

Application.Run

方法啟

動

的。

 

3

、

線

程外操作

GUI

控件的

問題

 

如果從另外一個

線

程操作

windows

窗體上的控件,

就會和主

線

程

產

生

競

爭,

造成不可

預

料的

結

果,

甚至死

鎖

。

因此

windows GUI

編

程有一個

規則

,

就是只能通

過創

建控件的

線

程來操作控件的數據,

否

則

就可能

產

生不可

預

料的

結

果。

 

因此,

dotnet

裡面,

為

了方便地解決

這

些

問題

,

Control

類實現

了

ISynchronizeInvoke

接口,提

供了

Invoke

和

BeginInvoke

方法來提供

讓

其它

線

程更新

GUI

界面控件的機制。

 

public interface ISynchronizeInvoke 

{ 

        

[HostProtection(SecurityAction.LinkDemand, 

Synchronization=true, 

ExternalThreading=true)] 

        

IAsyncResult BeginInvoke(Delegate method, object[] args); 

        

object EndInvoke(IAsyncResult result); 

        

object Invoke(Delegate method, object[] args); 

        

bool InvokeRequired { get; } 

} 

} 

如果從

線

程外操作

windows

窗體控件,那

麼

就需要使用

Invoke

或者

BeginInvoke

方法,通

過

一

個委托把

調

用封送到控件所屬的

線

程上

執

行。

 

二、消息機制

---

線

程

間

和

進

程

間

通信機制

 

1

、

window

消息

發

送

 

Windows

消息機制是

windows

平台上的

線

程或者

進

程

間

通信機制之一。

Windows

消息

值

其

實

就

是定

義

的一個數據

結

構,最重要的是消息的

類

型,它就是一個整數;

然後就是消息的參數。消息的

參數可以表示很多

東

西。

 

Windows

提供了一些

api

用來向一個

線

程的消息

隊

列

發

送消息。因此,一個

線

程可以向另一個

線

程的消息

隊

列

發

送消息從而告

訴對

方做什

麼

,

這樣

就完成了

線

程

間

的通信。

有些

api

發

送消息需要

一個窗口句柄,

這種

函數可以把消息

發

送到指定窗口的主

線

程消息

隊

列;

而有些

則

可以直接通

過線

程句柄,把消息

發

送到

該線

程消息

隊

列中。

 

 

 

                                                    

 

  

用消息機制通信

 

  

 

SendMessage

是

windows api

,用來把一個消息

發

送到一個窗口的消息

隊

列。

這

個方法是個阻塞

方法,

也就是操作系

統

會確保消息的確

發

送到目的消息

隊

列,

並且

該

消息被

處

理完

畢

以後,

該

函數

才返回。返回之前,

調

用者將會被

暫時

阻塞。

 

PostMessage

也是一個用來

發

送消息到窗口消息

隊

列的

api

函數,但

這

個方法是非阻塞的。也就

是它會

馬

上返回,而不管消息是否真的

發

送到目的地,也就是

調

用者不會被阻塞。

 

2

、

 

Invoke and BeginInvoke 

 

  

下載

還剩5頁未讀,繼續閱讀

 

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved