今天,在按照书上的一个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. poj1220:高精度进制转换模板题

    今天撸3708  一直奇怪的re 就先放下了,写这个题的过程中学习了一个高精度进制转换,用这个模板写了1220 记录一下: #include <iostream> #include < ...

  2. Linux的目录结构及其作用

    /bin bin是Binary的缩写.这个目录存放着最经常使用的命令. /boot这里存放的是启动Linux时使用的一些核心文件,包括一些连接文件以及镜像文件. /dev dev是Device(设备) ...

  3. (Problem 19)Counting Sundays

    You are given the following information, but you may prefer to do some research for yourself. 1 Jan ...

  4. 乐卡上海网点地图制作心得 | 百度地图API使用心得

    前言 事情的起因是我的爱人喜欢收集一些美丽的乐卡(明信片的一种,正面是美丽壮阔的风景照).作为一个坚实的后盾自然要支持她!于是我经常借着午休穿梭在大街小巷,凭借乐卡官方提供的乐卡网点地址进行寻找并取卡 ...

  5. 你知道android的MessageQueue.IdleHandler吗?

    WeTest 导读 干货!干货!或许可以是一种处理问题的新思路哟! 前言 我们知道android是基于Looper消息循环的系统,我们通过Handler向Looper包含的MessageQueue投递 ...

  6. Spider爬虫 の 事

      初识Spider_Man(爬爬虫) Spider_Man_2 の requests模块   Spider_Man_3 の selenium   Spider_Man_4 の BeautifulSo ...

  7. Luogu P2661 信息传递

    传送门 一眼就能看出来是个并查集 但是并不会写... 看了一下题解说是并查集求最小环qwq 所以,每次加入第i个小同学,判断如果他要告诉的小同学k最后会告诉他(也就是转回来了), 就说明出现了一个环, ...

  8. Ext根据条件显示隐藏列

    Ext根据条件显示隐藏列 写在ExtonReady函数里面,并在表格成功渲染之后,可以添加判断是否隐藏或者显示某一列 /* 判断是否显示版本号一列 */ var showVersionFlag = ' ...

  9. python3+selenium3+requests爬取我的博客粉丝的名称

    爬取目标 1.本次代码是在python3上运行通过的 selenium3 +firefox59.0.1(最新) BeautifulSoup requests 2.爬取目标网站,我的博客:https:/ ...

  10. jq的attr、prop和data区别

    prop()获取在匹配的元素集中的第一个元素的属性值. 大家都知道有的浏览器只要写disabled,checked就可以了,而有的要写成disabled = "disabled", ...