今天,在按照书上的一个winform例子做练习(实则就是边看边抄了一遍...)的时候,看到Application.DoEvents()这个方法,但是并不明白这个方法是做什么用的。只知道不用这个方法的话,在循环做耗时操作的时候,窗口ui绘制会出现问题。

于是在网上查找了一下,但是头昏脑涨的,那些理论和概念对我来讲,有点难懂。但是眼前我只是想理解这个方法的作用,于是便按照自己的理解去浅显的给它作出解释。

 private void btnCopy_Click(object sender, EventArgs e)
{
List<FileInfo> fileList = GetFileList();
foreach (FileInfo file in fileList)
{
try
{
labStatus.Text = "Copying " + txtTargetDir.Text + "\\" + file.Name + "...";
Application.DoEvents();
//复制文件到目标位置
file.CopyTo(txtTargetDir.Text + "\\" + file.Name, chbOverWrite.Checked);
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
labStatus.Text = "Done.";
}

上面的代码是我做练习时候的其中一段,目的是点击copy按钮的时候,在名为labStatus的label上显示一段文字,然后后台就copy一个文件,如此循环,直到要copy的文件全部copy完成,最后将labStatus上的文字变成Done。

如此运行的话,是没有什么问题的。但是我不太理解Application.DoEvents()方法在这里起了何种作用,于是将Application.DoEvents()注释掉再运行。当我点击copy之后,窗口像是“死掉”了一样,但是后台的文件确实是正在复制,复制完成之后,labStatus的text变成done。

在我查找资料的过程中,我才知道windows的消息机制。但是那些深入的理论,对于我目前来说有点看着头疼,看了也看不懂,又不会去用,看了也会忘记的。于是我浅显的了解了一点目前需要的。

以下看起来比较书面的文字,是我抄录来的。

1,消息,就是指Windows发出的一个通知,告诉应用程序某个事情发生了。例如,单击鼠标、改变窗口尺寸、按下键盘上的一个键都会使Windows发送一个消息给应用程序。

2,Windows的消息系统是由3个部分组成的:

  ·消息队列。Windows能够为所有的应用程序维护一个消息队列。应用程序必须从消息队列中获取消息,然后分派给某个窗口。
  ·消息循环。通过这个循环机制应用程序从消息队列中检索消息,再把它分派给适当的窗口,然后继续从消息队列中检索下一条消息,再分派给适当的窗口,依次进行。

  ·窗口过程。每个窗口都有一个窗口过程来接收传递给窗口的消息,它的任务就是获取消息然后响应它。窗口过程是一个回调函数;处理了一个消息后,它通常要返回一个值给Windows。

3,一个消息从产生到被一个窗口响应,其中有5个步骤:

  1) 系统中发生了某个事件。

  2) Windows把这个事件翻译为消息,然后把它放到消息队列中。

  3)应用程序从消息队列中接收到这个消息,把它存放在TMsg记录中。

  4)应用程序把消息传递给一个适当的窗口的窗口过程。

  5) 窗口过程响应这个消息并进行处理。

  步骤3和4构成了应用程序的消息循环。消息循环往往是Windows应用程序的核心,因为消息循环使一个应用程序能够响应外部的事件。消息循环的任务就是从消息队列中检索消息,然后把消息传递给适当的窗口。如果消息队列中没有消息,Windows就允许其他应用程序处理它们的消息。

到这里也就差不多了,其他的资料看了也没看,大概能看懂的也记不住,就不提了。那么回到原本的话题上来,Application.DoEvents()方法在这里起了什么作用?

我的比较浅显的理解是,在上面那段代码里,当我们点击copy按钮之后,在循环中,每一次windows都往当前消息队列里添加了两个消息,一个是labStatus的text要改变,另一个是要copy一个文件,然而copy一个文件很明显是比较耗时的操作。在我注释掉Application.DoEvents()这行代码之后,从运行的窗口展现出来的效果来看,很显然,它是先将copy文件的那个消息响应了,然后在所有的copy文件操作都执行完了之后,再去响应了labStatus的text改变操作,但是一次性执行循环里的所有labStatus的text改变操作的话,我们就只能看得见最后的 labStatus.Text = "Done.";所产生的效果了。当然,在copy过程中,我们要去点击窗口,或者拖动窗口,这些操作是要等到copy之后的。

所以,Application.DoEvents()方法所做的事情,正如它的介绍一样——处理当前在消息队列里的所有windows消息。

但是我还是有很多很多不明白的地方,比如为什么是先响应了copy操作呢?这个队列是怎么排列的呀?不过现在暂且就这样了。以上就是我的个人的理解,它或许根本就是错误的,或许有许多很幼稚的地方,请看到的朋友们告诉我,帮助我的学习,也顺便巩固下您自己。谢谢!

Application.DoEvents()的更多相关文章

  1. Application.DoEvents()的使用

    最近做了一个个人数字图书馆管理系统,因为牵扯到电脑文件的扫描,想做一个实时显示当前扫面文件的功能,就类似于360文件扫描时的效果,本来打算用多线程来实现,但是方法太多没有实现,后来在程序中进行控制,由 ...

  2. C#中Application.DoEvents()的作用

    Visual Studio里的摘要:处理当前在消息队列中的所有 Windows 消息. 交出CPU控制权,让系统可以处理队列中的所有Windows消息,比如在大运算量循环内,加Application. ...

  3. (转).net Application.DoEvents()的作用

    原文地址:http://blog.csdn.net/weinierbian/article/details/6231589 Application.DoEvents()的作用:处理所有的当前在消息队列 ...

  4. C#经典之Application.DoEvents()的使用

    最近做了一个文件上传的模块,因为牵扯到电脑文件的扫描,想做一个实时显示当前扫面文件的功能,就类似于360文件扫描时的效果,本来打算用多线程来实现,但是方法太多没有实现,后来在程序中进行控制,由于文件太 ...

  5. Application.DoEvents()的作用

    记得第一次使用Application.DoEvents()是为了在加载大量数据时能够有一个数据加载的提示,不至于系统出现假死的现象,当时也没有深入的去研究他的原理是怎样的,结果在很多地方都用上了App ...

  6. Self-Host c#学习笔记之Application.DoEvents应用 不用IIS也能執行ASP.NET Web API

    Self-Host   寄宿Web API 不一定需要IIS 的支持,我们可以采用Self Host 的方式使用任意类型的应用程序(控制台.Windows Forms 应用.WPF 应用甚至是Wind ...

  7. C# Winform中慎用Application.DoEvents

    private void Add() { ; i < ; i++) { Button button = new Button(); button.Width = ; button.Height ...

  8. 关于Application.DoEvents()==转

    记得第一次使用Application.DoEvents()是为了在加载大量数据时能够有一个数据加载的提示,不至于系统出现假死的现象,当时也没有深入的去研究他的原理是怎样的,结果在很多地方都用上了App ...

  9. Application.DoEvents()和多线程

    首先将以下代码放到Button事件里面: private void btnStart_Click(object sender, EventArgs e)  {      for (int q = 0; ...

随机推荐

  1. 滚动页面时DIV到达顶部时固定在顶部

    本示例使用Javascript实现了滚动页面时,DIV到达顶部时固定在顶部.在IE下效果有点闪,效果网址:http://www.keleyi.com/keleyi/phtml/fixdiv.htm 下 ...

  2. python学习第二天 --变量及其字符串

    python变量: 在计算机程序中,变量不仅可以是数字,还可以是任意数据类型. 在Python程序中,变量是用一个变量名表示,变量名必须是大小写英文.数字和下划线(_)的组合,且不能用数字开头. 在P ...

  3. R语言画正弦曲线

    正弦曲线一个周期是2π,我们要先生成x的取值范围. 可以用seq函数生成一个等差序列,步进为0.01 x=seq( 0,  2*pi,  0.01 )   pi表示π y=sin(x) plot(x, ...

  4. Codeforces Round #277 (Div. 2) 解题报告

    题目地址:http://codeforces.com/contest/486 A题.Calculating Function 奇偶性判断,简单推导公式. #include<cstdio> ...

  5. TinyURL缩短网址服务 - Blog透视镜

    TinyURL是个缩短网址服务的网站,提供1个短网址转向指定到长网址,像是杂志书籍中若有网址太长,也都会用TinyURL来缩短网址,例如本篇文章:http://blog.openyu.org/2014 ...

  6. 设置ActioinBar 的背景色以及Title的字体颜色

    //设置ActionBar背景 Drawable draw=this.getResources().getDrawable(R.drawable.actionbar_bg); getActionBar ...

  7. 2015北大夏令营day1 B:An Idea of Mr. A

    题意:给定一个范围l,r计算i,j(i<j)属于这个范围内的gcd(2^(2^i)+1,2^(2^j)+1)的总和. 思路:费马数的应用,让我惊呆的是当年居然有123个人会做,我tm毛都不会.. ...

  8. LeetCode_Unique Binary Search Trees

    Given n, how many structurally unique BST's (binary search trees) that store values 1...n? For examp ...

  9. 【转】Java基本数据类型

    原文网址:http://blog.csdn.net/bingduanlbd/article/details/27790287 Java语言是静态类型的(statical typed),也就是说所有变量 ...

  10. jquery IE6 select.val() bug报错解决办法

    原文地址:http://hi.baidu.com/kinghmx/item/395dbac3261292dcef183b52 最近在写一个页面,在出了ie6外的所有浏览器中都正常(ie7,8,9,  ...