对于VS 2008 工具箱的学习,首先碰到的就是环境的配置。以前学的VS 2003工具箱,但并没有怎么用。所以有一个星期的时间基本是在用实践着.net 1.0,工具箱有许多功能可以学习介绍。
Windows程序有个消息队列,窗体上的所有消息是这个队列里面消息的最主要来源。这里的while循环使用了GetMessage()这个方法,这是个阻塞方法,也就是队列为空时方法就会被阻塞,从而这个while循环停止运动,这避免了一个程序把cpu无缘无故地耗尽,让其它程序难以得到响应。
当然在某些需要cpu***限度运动的程序里面就可以使用另外的方法,例如某些3d游戏或者及时战略游戏中,VS 2008 工具箱一般会使用PeekMessage()这个方法,它不会被windows阻塞,从而保证整个游戏的流畅和比较高的帧速。
这个主线程维护着整个窗体以及上面的子控件。当它得到一个消息,就会调用DispatchMessage方法派遣消息,这会引起对窗体上的窗口过程的调用。窗口过程里面当然是程序员提供的窗体数据更新代码和其它代码。#t#
Invoke或者BeginInvoke方法都需要一个委托对象作为参数。委托类似于回调函数的地址,VS 2008 工具箱因此调用者通过这两个方法就可以把需要调用的函数地址封送给界面线程。这些方法里面如果包含了更改控件状态的代码,那么由于最终执行这个方法的是界面线程,从而避免了竞争条件,避免了不可预料的问题。如果其它线程直接操作界面线程所属的控件,那么将会产生竞争条件,造成不可预料的结果。
使用VS 2008 工具箱完成一个委托方法的封送,就类似于使用SendMessage方法来给界面线程发送消息,VS 2008 工具箱是一个同步方法。也就是说在Invoke封送的方法被执行完毕前,Invoke方法不会返回,从而调用者线程将被阻塞。
使用BeginInvoke方法封送一个委托方法,类似于使用PostMessage进行通信,这是一个异步方法。也就是该方法封送完毕后马上返回,不会等待委托方法的执行结束,调用者线程将不会被阻塞。但是调用者也可以使用EndInvoke方法或者其它类似WaitHandle机制等待异步操作的完成。
但是在内部实现上,Invoke和BeginInvoke都是用了PostMessage方法,从而VS 2008 工具箱避免了SendMessage带来的问题。而Invoke方法的同步阻塞是靠WaitHandle机制来完成的。