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 

 

  

posted @ 2016-11-15 16:17  林云夕  阅读(6396)  评论(1编辑  收藏  举报