Application.DoEvents()
今天,在按照书上的一个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。
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()的更多相关文章
- Application.DoEvents()的使用
最近做了一个个人数字图书馆管理系统,因为牵扯到电脑文件的扫描,想做一个实时显示当前扫面文件的功能,就类似于360文件扫描时的效果,本来打算用多线程来实现,但是方法太多没有实现,后来在程序中进行控制,由 ...
- C#中Application.DoEvents()的作用
Visual Studio里的摘要:处理当前在消息队列中的所有 Windows 消息. 交出CPU控制权,让系统可以处理队列中的所有Windows消息,比如在大运算量循环内,加Application. ...
- (转).net Application.DoEvents()的作用
原文地址:http://blog.csdn.net/weinierbian/article/details/6231589 Application.DoEvents()的作用:处理所有的当前在消息队列 ...
- C#经典之Application.DoEvents()的使用
最近做了一个文件上传的模块,因为牵扯到电脑文件的扫描,想做一个实时显示当前扫面文件的功能,就类似于360文件扫描时的效果,本来打算用多线程来实现,但是方法太多没有实现,后来在程序中进行控制,由于文件太 ...
- Application.DoEvents()的作用
记得第一次使用Application.DoEvents()是为了在加载大量数据时能够有一个数据加载的提示,不至于系统出现假死的现象,当时也没有深入的去研究他的原理是怎样的,结果在很多地方都用上了App ...
- Self-Host c#学习笔记之Application.DoEvents应用 不用IIS也能執行ASP.NET Web API
Self-Host 寄宿Web API 不一定需要IIS 的支持,我们可以采用Self Host 的方式使用任意类型的应用程序(控制台.Windows Forms 应用.WPF 应用甚至是Wind ...
- C# Winform中慎用Application.DoEvents
private void Add() { ; i < ; i++) { Button button = new Button(); button.Width = ; button.Height ...
- 关于Application.DoEvents()==转
记得第一次使用Application.DoEvents()是为了在加载大量数据时能够有一个数据加载的提示,不至于系统出现假死的现象,当时也没有深入的去研究他的原理是怎样的,结果在很多地方都用上了App ...
- Application.DoEvents()和多线程
首先将以下代码放到Button事件里面: private void btnStart_Click(object sender, EventArgs e) { for (int q = 0; ...
随机推荐
- python中的函数存入list中的实例
最近由于接触了python这个强大的东西,在写代码时考虑到代码的扩展性,就想到了将python的函数名存入list中.有点像习惯的c/c++中的函数指针的意思. 下面上代码: # coding=utf ...
- 异步编程设计模式Demo - PrimeNumberCalculator
using System; using System.Collections; using System.Collections.Specialized; using System.Component ...
- 【iOS开发】添加子控件方式(懒加载,GCC)
// // ViewController.m // GCC // // Created by admin on 15/10/7. // Copyright © 2015年 admin. All rig ...
- ExpandableListView 保证只展开一组
expandableListView.setOnGroupExpandListener(new OnGroupExpandListener(){ @Override public void onGro ...
- 《Programming WPF》翻译 第9章 3.自定义功能
原文:<Programming WPF>翻译 第9章 3.自定义功能 一旦你挑选好一个基类,你将要为你的控件设计一个API.大部分WPF元素提供属性暴露了多数功能,事件,命令,因为他们从框 ...
- (转)open和fopen的区别:
fopen与open的区别 open和fopen的区别: 1.缓冲文件系统缓冲文件系统的特点是:在内存开辟一个“缓冲区”,为程序中的每一个文件使用,当执行读文件的操作时,从磁盘文件将数据先读入内存“缓 ...
- Codeforces243C-Colorado Potato Beetle(离散化+bfs)
Old MacDonald has a farm and a large potato field, (1010 + 1) × (1010 + 1) square meters in size. Th ...
- IOS开发错误提示原因集合-----长期更新
"[__NSCFConstantString size]: unrecognized selector sent to instance." =>将NSString类型的参数 ...
- Unity 脚本函数生命周期
Awake(),一般我们在这里做一些组件的获得,比如使用getcomponent方法. Start(),我们可以在这里给变量赋值. FixUpdate(),固定更新,因为这里得更新速度为固定(可以在T ...
- 04747_Java语言程序设计(一)_第3章_面向对象编程基础
链式编程 每次调用方法后,返回的是一个对象 /* * 链式编程 * 每次调用方法后,返回的是一个对象 */ class Student { public void study() { System.o ...