当前位置: 首页 > news >正文

网站开发报价技巧珠海中企网站建设

网站开发报价技巧,珠海中企网站建设,关于网站建设项目收取费用,建筑模板规格1. Windows程序消息机制 Windows GUI程序是基于消息机制的,有个主线程维护着消息泵。这个消息泵让windows程序生生不息。 Windows程序有个消息队列#xff0c;窗体上的所有消息是这个队列里面消息的最主要来源。这里的While循环使用了GetMessage() 这个方法,这是个阻塞方法,也…1. Windows程序消息机制 Windows GUI程序是基于消息机制的,有个主线程维护着消息泵。这个消息泵让windows程序生生不息。 Windows程序有个消息队列窗体上的所有消息是这个队列里面消息的最主要来源。这里的While循环使用了GetMessage() 这个方法,这是个阻塞方法,也就是队列为空时方法就会阻塞,从而这个While循环停止运动,这避免了一个程序把cpu无缘无故的耗尽,让其他程序难以得到响应。当然在某些需要cpu最大限度运动的程序里面就可以使用另外的方法例如某些3d游戏或者及时战略游戏中一般会使用PeekMessage这个方法它不会被windows阻塞从而保证整个游戏的流畅和比较高的帧速。(PeekMessage是一个Windows API函数。该函数为一个消息检查线程消息队列并将该消息如果存在放于指定的结构。DispatchMessage功能是发送消息给窗口窗口收到消息执行事件)。 这个主线程维护着整个窗体以及上面的子控件。当它得到一个消息,就会调用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, Synchronizationtrue, ExternalThreadingtrue)]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 Invoke或者BeginInvoke方法都需要一个委托对象作为参数。委托类似于回调函数的地址因此调用者通过这两个方法就可以把需要调用的函数地址封送给界面线程。这些方法里面如果包含了更改控件状态的代码那么由于最终执行这个方法的是界面线程从而避免了竞争条件避免了不可预料的问题。如果其它线程直接操作界面线程所属的控件那么将会产生竞争条件造成不可预料的结果。 使用Invoke完成一个委托方法的封送就类似于使用SendMessage方法来给界面线程发送消息是一个同步方法。也就是说在Invoke封送的方法被执行完毕前Invoke方法不会返回从而调用者线程将被阻塞。 使用BeginInvoke方法封送一个委托方法类似于使用PostMessage进行通信这是一个异步方法。也就是该方法封送完毕后马上返回不会等待委托方法的执行结束调用者线程将不会被阻塞。但是调用者也可以使用EndInvoke方法或者其它类似WaitHandle机制等待异步操作的完成。 但是在内部实现上Invoke和BeginInvoke都是用了PostMessage方法从而避免了SendMessage带来的问题。而Invoke方法的同步阻塞是靠WaitHandle机制来完成的。 3、使用场合问题 如果你的后台线程在更新一个UI控件的状态后不需要等待而是要继续往下处理那么你就应该使用BeginInvoke来进行异步处理。 如果你的后台线程需要操作UI控件并且需要等到该操作执行完毕才能继续执行那么你就应该使用Invoke。否则在后台线程和主截面线程共享某些状态数据的情况下如果不同步调用而是各自继续执行的话可能会造成执行序列上的问题虽然不发生死锁但是会出现不可预料的显示结果或者数据处理错误。 可以看到ISynchronizeInvoke有一个属性InvokeRequired。这个属性就是用来在编程的时候确定一个对象访问UI控件的时候是否需要使用Invoke或者BeginInvoke来进行封送。如果不需要那么就可以直接更新。在调用者对象和UI对象同属一个线程的时候这个属性返回false。在后面的代码分析中我们可以看到Control类对这一属性的实现就是在判断调用者和控件是否属于同一个线程的。 三、Delegate.BeginInvoke 通过一个委托来进行同步方法的异步调用也是.net提供的异步调用机制之一。但是Delegate.BeginInvoke方法是从ThreadPool取出一个线程来执行这个方法以获得异步执行效果的。也就是说如果采用这种方式提交多个异步委托那么这些调用的顺序无法得到保证。而且由于是使用线程池里面的线程来完成任务使用频繁会对系统的性能造成影响。 Delegate.BeginInvoke也是讲一个委托方法封送到其它线程从而通过异步机制执行一个方法。调用者线程则可以在完成封送以后去继续它的工作。但是这个方法封送到的最终执行线程是运行库从ThreadPool里面选取的一个线程。 这里需要纠正一个误区那就是Control类上的异步调用BeginInvoke并没有开辟新的线程完成委托任务而是让界面控件的所属线程完成委托任务的。看来异步操作就是开辟新线程的说法不一定准确。 四、用Reflector察看一些相关代码 1、Control.BeginInvoke and Control.Invoke public IAsyncResult BeginInvoke(Delegate method, params object[] args) {using (new MultithreadSafeCallScope()){return (IAsyncResult) this.FindMarshalingControl().MarshaledInvoke(this, method, args, false);} } public object Invoke(Delegate method, params object[] args) {using (new MultithreadSafeCallScope()){return this.FindMarshalingControl().MarshaledInvoke(this, method, args, true);} } 这里的FindMarshalingControl方法通过一个循环向上回溯从当前控件开始回溯父控件直到找到最顶级的父控件用它作为封送对象。例如我们调用窗体上一个进度条的Invoke方法封送委托但是实际上会回溯到主窗体通过这个控件对象来封送委托。因为主窗体是主线程消息队列相关的发送给主窗体的消息才能发送到界面主线程消息队列。 我们可以看到Invoke和BeginInvoke方法使用了同样的实现只是MarshaledInvoke方法的最后一个参数值不一样。 2. 2、MarshaledInvoke private object MarshaledInvoke(Control caller, Delegate method, object[] args, bool synchronous) {int num;if (!this.IsHandleCreated){throw new InvalidOperationException(SR.GetString(ErrorNoMarshalingThread));}if (((ActiveXImpl) this.Properties.GetObject(PropActiveXImpl)) ! null){IntSecurity.UnmanagedCode.Demand();}bool flag false;if ((SafeNativeMethods.GetWindowThreadProcessId(new HandleRef(this, this.Handle), out num) SafeNativeMethods.GetCurrentThreadId()) synchronous){flag true;}ExecutionContext executionContext null;if (!flag){executionContext ExecutionContext.Capture();}ThreadMethodEntry entry new ThreadMethodEntry(caller, method, args, synchronous, executionContext);lock (this){if (this.threadCallbackList null){this.threadCallbackList new Queue();}}lock (this.threadCallbackList){if (threadCallbackMessage 0){threadCallbackMessage SafeNativeMethods.RegisterWindowMessage(Application.WindowMessagesVersion _ThreadCallbackMessage);}this.threadCallbackList.Enqueue(entry);}if (flag){this.InvokeMarshaledCallbacks();}else{//终于找到你了PostMessageUnsafeNativeMethods.PostMessage(new HandleRef(this, this.Handle), threadCallbackMessage, IntPtr.Zero, IntPtr.Zero);}if (!synchronous) //如果是异步那么马上返回吧{return entry;}if (!entry.IsCompleted) //同步调用没结束阻塞起来等待吧{this.WaitForWaitHandle(entry.AsyncWaitHandle);}if (entry.exception ! null){throw entry.exception;}return entry.retVal; } 怎么样我们终于看到PostMessage了吧通过windows消息机制实现了封送。而需要封送的委托方法作为消息的参数进行了传递。关于其它的代码这里不作进一步解释。 3、InvokeRequired public bool InvokeRequired {get{using (new MultithreadSafeCallScope()){HandleRef ref2;int num;if (this.IsHandleCreated){ref2 new HandleRef(this, this.Handle);}else{Control wrapper this.FindMarshalingControl();if (!wrapper.IsHandleCreated){return false;}ref2 new HandleRef(wrapper, wrapper.Handle);}int windowThreadProcessId SafeNativeMethods.GetWindowThreadProcessId(ref2, out num);int currentThreadId SafeNativeMethods.GetCurrentThreadId();return (windowThreadProcessId ! currentThreadId);}} } 终于看到了这是在判断windows窗体线程和当前的调用者线程是否是同一个如果是同一个就没有必要封送了直接访问这个GUI控件吧。否则就不要那么直接表白了就需要Invoke或者BeginInvoke做媒了。
http://www.pierceye.com/news/557194/

相关文章:

  • 网站建设与运营实验开发一个网站的成本
  • 自考网站建设与管理资料郑州高端网站建设哪家好
  • 网站设计开发维护设计云网站
  • 北京工商局网站怎么做增资h5个人页面制作
  • 北京好的网站建设12个 网站模板 管理办法
  • vs2017 如何做网站最近一周新闻热点大事件
  • wordpress建站欣赏解释网站为什么这样做
  • 网站建设模板登录界面七牛wordpress插件
  • 手机 网站制作上饶企业网站建设
  • 网站建设需要知道什么软件深达网站制作深圳公司
  • 怎么做监控网站Wordpress页面函数
  • 梁平网站建设百度搜索排名优化哪家好
  • 芜湖网站建设芜湖狼道cad精品课网站建设
  • qq空间认证的网站后台根目录seo和sem是什么意思
  • 中国建设集团门户网站装修公司做网站
  • 东莞seo建站公司哪家好怎么把网站推广出去
  • 网站建设什么时候好豆瓣wordpress
  • 动漫网站设计报告最好的wordpress商城主题
  • 陕西餐饮加盟网站建设如何做一个网站代码
  • 合浦住房和城乡规划建设局网站网页设计培训机构学什么好
  • 做网站需要注意的地方模板ppt
  • 自己建立公司网站自助建站系统
  • 淅川微网站开发wordpress 侧边收起
  • 网站建设企业哪家好乐清站在那儿
  • 网站建设公司人员配置做网站衡水
  • 成都网站建设939seo搜索优化软件
  • 企业网站建设哪家好seo检测
  • 网站建设的案例教程视频教程兴平市住房和城乡建设局门户网站
  • cps推广网站怎么制作网站图片不显示
  • 手机网站设计图尺寸网站里的课程配图怎么做