消息循环

Win32窗体程序基于消息驱动的,程序的模型就是一个用户触发事件消息->系统分发事件消息->程序处理事件的循环过程.

.NET Win Form程序对消息循环进行了封装,可以看到Application.Run方法其实就是在当前UI线程启动一个消息循环.

工作线程

每个Win Form进程默认会开启两个线程:

  • 一个是主线程,即我们熟知的UI线程,所有的程序处理默认都在此线程上运行.
  • 另外一个线程是用于监听处理系统级事件的,如系统注销等,详细的系统事件列表可见SystemEvents类的说明.
    在单独线程上处理系统级事件,就不会造成程序阻塞.

下面通过在系统事件处理过程中增加断点,确定系统事件处理是在单独的名字为.NET SystemEvents线程上运行的.

强制重绘

既然系统默认只有一个线程做应用程序的处理.如果在一个长时间的处理过程中,又发生了其他事件,譬如界面无效需要重绘事件,或者就是一个用户点击了一个按钮,由于是单线程,这些后续事件只能等待处理,造成了界面不更新或者就是假死的现象.

下面的代码通过在特定的事件内循环更新界面上的label文本来模拟模拟一个长时间的操作.

可以看到,界面上的label文本在最后才会更新,并没有按照预期更新.

如果想实时更新,就需要通过执行Refresh方法去重绘界面.

过程中处理其他事件

在处理当前事件的过程中,如果需要响应其它事件消息,可以通过Application.DoEvents()方法来实现.

譬如前面的例子中,如果用户点击了退出按钮,程序需要马上退出.在没有在过程中加入DoEvents方法的情况下,程序只会等待直到整个长时间执行过程完成后才会退出.如果马上响应退出,就在过程中调用DoEvents方法来实时处理消息.

效果:

前面的方法合理吗?

Application.DoEvents()方法中断了当前的操作,而跳去了处理其他事件.如果在其他事件处理代码中,可能又会触发其他事件,这样会出现不可预料的结果,或者会引致死循环(后面的事件又触发了最初的事件).

对于耗时任务,我们自然想到多线程处理.
so创建一个工作线程,并把那个长时间的任务分配到此新线程上执行.

运行代码,发现异常了.

原来,为保证线程安全,.NET控件不允许从非创建它的线程上访问它.否则,不同线程访问控件,很容易会造成问题.
譬如数据脏读.或者你说加锁访问吧,但这会引致另外一个问题:死锁.
要处理这个问题,可以有以下方法:

  1. 蒙着眼睛,设置Control.CheckForIllegalCrossThreadCalls=False跳过检测.
  2. 乖乖遵守规定,各司其职,在UI线程上去访问控件,方法很简单,利用Control.Invoke()方法.

    效果,一切正常:
  3. 上面第二个方法需要处理低级的线程操作问题,需要手工创建线程,退出(Abort)线程.其实.NET已经提供了BackgroundWorker这个类封装了后台线程的相关操作,而且是基于事件模型的,很容易使用.下面用BackGroundWorker这个类改写一个程序.
      a.创建对象并初始化

    b.事件处理代码.


              效果:
             

参考

How to: Make Thread-Safe Calls to Windows Forms Controls

Threading in a windows form

Win Form程序线程点点的更多相关文章

  1. WPF / Win Form:多线程去修改或访问UI线程数据的方法( winform 跨线程访问UI控件 )

    WPF:谈谈各种多线程去修改或访问UI线程数据的方法http://www.cnblogs.com/mgen/archive/2012/03/10/2389509.html 子线程非法访问UI线程的数据 ...

  2. 如何捕获Wince下form程序的全局异常

    前言 上两篇文章我们总结了在winform程序下如何捕获全局的异常.那么同样的问题,在wince下我们如何来处理呢?用相同的代码来处理可以吗? 答案是否定的,上面的方案1完全不能解决wince下的情况 ...

  3. WPF调用Win Form

    WPF是win form的下一代版本,现在越来越多的公司使用WPF.如何兼容已有的使用win form开发的应用程序呢?下面有三种方式来在WPF中调用win form. 使用WPF中的WindowsF ...

  4. Android应用程序线程消息循环模型分析

    文章转载至CSDN社区罗升阳的安卓之旅,原文地址:http://blog.csdn.net/luoshengyang/article/details/6905587 我们知道,Android应用程序是 ...

  5. Java虚拟机性能管理神器 - VisualVM(7) 排查JAVA应用程序线程泄漏【转】

    Java虚拟机性能管理神器 - VisualVM(7) 排查JAVA应用程序线程泄漏[转] 标签: javajvm线程泄漏 2015-03-11 19:47 1098人阅读 评论(0) 收藏 举报   ...

  6. Java虚拟机性能管理神器 - VisualVM(9) 排查JAVA应用程序线程死锁【转】

    Java虚拟机性能管理神器 - VisualVM(9) 排查JAVA应用程序线程死锁[转] 标签: javajvm监控工具性能优化 2015-03-11 19:59 1948人阅读 评论(0) 收藏  ...

  7. 性能追击:万字长文30+图揭秘8大主流服务器程序线程模型 | Node.js,Apache,Nginx,Netty,Redis,Tomcat,MySQL,Zuul

    本文为<高性能网络编程游记>的第六篇"性能追击:万字长文30+图揭秘8大主流服务器程序线程模型". 最近拍的照片比较少,不知道配什么图好,于是自己画了一个,凑合着用,让 ...

  8. Linux C 程序 线程(18)

    线程控制 1.线程与进程的关系 线程:计算机中独立运行的最小单位. 在用户角度:多个线程是同时执行的. 操作系统角度:各个线程交替执行 以上只针对单核CPU的情况 在多核CPU主机上,多个线程可以同时 ...

  9. Ninject之旅之十二:Ninject在Windows Form程序上的应用(附程序下载)

    摘要: 下面的几篇文章介绍如何使用Ninject创建不同类型的应用系统.包括: Windows Form应用系统 ASP.NET MVC应用系统 ASP.NET Web Form应用系统 尽管对于不同 ...

随机推荐

  1. javascript创建文档碎片节点

    在<javascript高级程序设计>一书的6.3.5:创建和操作节点一节中,介绍了几种动态创建html节点的方法,其中有以下几种常见方法: · crateAttribute(name): ...

  2. 妙方之解决matplotlib的图例里的中文呈现小方形

    妙方之解决matplotlib的图例里的中文呈现小方形 分析思路: 每个中文都对应地呈现一个小方形, 不多也不少. 不能说是乱码. 应该是matplotlib的默认字库不支持中文造成的. 应对办法: ...

  3. 自动生成.py文件头部的C语言小程序

    每次都 vi xxx.py 然后再打 #!/usr/bin/env python 等等的程序头信息感觉有点麻烦,于是便想着写一个小程序自动生成这些头信息了,顺便在 ~/.bashrc 里写入 alia ...

  4. commons-io ProxyInputStream,ProxyOutputStream,ProxyReader,ProxyWriter

    1.ProxyInputStream: A Proxy stream which acts as expected, that is it passes the method calls on to ...

  5. C# 拆箱与装箱 要严格控制,数量多起来严重影响效率

    int i = 5; object o = i; int j = (int)o; IComparer x = 5; 1. o的对象必须为一个引用,而数字5不是,则发生了装箱: 运行时将在堆上创建一个包 ...

  6. IDEA建立---- java web项目

    1.新建一个javaweb项目 2.给项目命名 3.建立完的项目结构大概是这样(在web 下新建 两个目录lib 和 classes) 4.找到project Structure---------&g ...

  7. Isometric terrain

    Isometric terrainhttp://forum.mapeditor.org/t/isometric-terrain/192/2 无透视地图的地形制作时,将每一贴图逆时针旋转45度,则比较容 ...

  8. 关于Application.Lock和Lock(obj) 转 http://www.cnblogs.com/yeagen/archive/2012/03/01/2375610.html

    关于Application.Lock和Lock(obj) Posted on 2012-03-01 15:28 billpeng 阅读(3498) 评论(3) 编辑 收藏 1.Application. ...

  9. [HTML/HTML5]3 页面结构

    在HTML5之前,主要的容器元素是div元素,但在HTML5中提供了数种其它容器元素供我们使用. 因此,当组织Web页面结构时,首先使用HTML将内容分成多部分,然后在对其使用CSS应用样式和格式. ...

  10. trim(),正则表达式中文匹配

    ^[/u4E00-/u9FA5]+$ 匹配中文 验证Email地址:“^w+[-+.]w+)*@w+([-.]w+)*.w+([-.]w+)*$”  验证InternetURL:“^http://([ ...