System.Windows.Forms.Application.DoEvents();
关于Application.DoEvents()的小研究
在MSDN中的备注是:
当运行 Windows 窗体时,它将创建新窗体,然后该窗体等待处理事件。该窗体在每次处理事件时,均将处理与该事件关联的所有代码。所有其他事件在队列中等待。在代码处理事件时,应用程序并不响应。例如,当将另一窗口拖到该窗口前面时,该窗口不重新绘制。
如果在代码中调用 DoEvents,则您的应用程序可以处理其他事件。例如,如果您有向 ListBox 添加数据的窗体,并将 DoEvents 添加到代码中,那么当将另一窗口拖到您的窗体上时,该窗体将重新绘制。如果从代码中移除 DoEvents,那么在按钮的单击事件处理程序执行结束以前,您的窗体不会重新绘制。
刚开始接触这段话的时候,会读不懂。所以我就去找了篇文章,文章中通过一个循环输出文本的例子解释了通过这段代码可以给人带来很好的用户体验( 不加的话程序只会显示输出循环最后的结果,但是加了以后会实时的输出),从而消除了认为进程死掉的情况。他还提到了用这个的缺点是影响了进程的效率,并通过了一个测验证实他的观点。
看了他的博客,我也就仿照他的说明写了个代码进行了测验,第一个代码是同他说的一样,加不加代码的效果是不同的。但是第二个,因为用一个计时器来计时。我因为不是很懂计时器,我就写了个类似计时器的代码,原理感觉上和他的差不多。
原理是:用Timer组件,写了一个Tick事件并设置了间隔时间,在事件内用了一个counter 来计数,再通过计数的结果已经响应的时间间隔来计算时间。再运行加了DoEvents代码的运行的很好,和我想的一样。
运行后发现,textBox2.可以得到99999就是结果的值,但是 label2却一直是零,也就相当于没有触发Tick事件,这就把给搞昏了,我明明是设定了Timer的Start而且也在循环之前调用的Tick 事件,这是为什么呢?我又试着将代码里的stop 给注释掉,再运行,在循环结束后可以运行Tick 事件了。从这个结果来看,开始以为Tick本来是可以运行的。因为Tick的触发是在当指定的计时器间隔已过去而且计时器处于启用状态时发生。那么有可能时间间隔太长,导致时间间隔没解释,也就是Tick来不及触发。为了验证这个是否正确,我将时间间隔调小,但是结果还是那样,而且到后来我直接将Tick的事件触发代码带到了循环中,可结果还是那样。到此,我想也许是存在优先级的概念,是否循环这个进程的优先级比Tick的优先级高。之前在循环体内设置的到99999后的Stop掉Timer,直接导致Tick刚要执行就被强行关掉了。因为MSDN上也查不到这方面的原因,我就此当做是结论了。
从这个测验后再回头想DoEvents的功能,我就想DoEvents就好比实现了进程的同步。在不加的时候,因为优先级的问题,程序会执行主进程的代码,再执行Tick的代码,而加了以后就可以同步执行。
从这个测验后再回头想DoEvents的功能,我就想DoEvents就好比实现了进程的同步。在不加的时候,因为优先级的问题,程序会执行主进程的代码,再执行Tick的代码,而加了以后就可以同步执行。
再回想那位网友在博客里写到的:
http://www.cnblogs.com/datong/archive/2008/04/06/1139216.html
关于Application.DoEvents()
记得第一次使用Application.DoEvents()是为了在加载大量数据时能够有一个数据加载的提示,不至于系统出现假死的现象,当时也没有深入的去研究他的原理是怎样的,结果在很多地方都用上了Application.DoEvents(),今天看到了关于这方面的一些文章,知道我以前有些用法是不当的,有些地方需要慎用Application.DoEvents()。
首先我们先看看在循环比较大的程序中,它的作用还是不错的,起到了一个实时响应的效果,例如:
for (int q = 0; q < 1000000; q++)
{
textBox1.Text = q.ToString();
Application.DoEvents();//实时响应文本框中的值
}
如果没有加上 DoEvents的话,由于循环时间会比较久就会出现假死的状态,而且程序不能处理其他的事件。而如果加上DoEvents的话就会对文本框的值实时响应,给用户带来较好的用户体验,可是DoEvents也带来了效率上的问题,处理同样的一个事件调用了DoEvents后效率降低了好几倍,这也是为什么要慎用的原因了。
现在来分析的话,就可以解释为什么,加了这行代码后。程序就会出实现类似双线程的功能,他会去寻找是否有别的事件,因为有这段时间才使得数值有时间可以显现。
System.Windows.Forms.Application.DoEvents();的更多相关文章
- 【C#遗补】获取应用程序路径之System.IO.Directory.GetCurrentDirectory和System.Windows.Forms.Application.StartupPath的区别
原文:[C#遗补]获取应用程序路径之System.IO.Directory.GetCurrentDirectory和System.Windows.Forms.Application.StartupPa ...
- Catch Application Exceptions in a Windows Forms Application
You need to handle the System.Windows.Forms.Application.ThreadException event for Windows Forms. Thi ...
- System.Windows.Forms.Timer反编译学习
using System; using System.ComponentModel; using System.Globalization; using System.Runtime; using S ...
- Unity 读取、写入自定义路径文件,调用System.Windows.Forms
调用System.Windows.Forms DLL 首先在Unity新建Plugins文件夹添加System.Windows.Forms.dll 然后代码中添加引用 using System; us ...
- Windows Forms Application Creation and Initialization
Windows Forms Application Creation and Initialization This topic details the steps performed after a ...
- System.Windows.Forms
File: winforms\Managed\System\WinForms\DataGridView.cs Project: ndp\fx\src\System.Windows.Forms.cspr ...
- WPF中实例化Com组件,调用组件的方法时报System.Windows.Forms.AxHost+InvalidActiveXStateException的异常
WPF中实例化Com组件,调用组件的方法时报System.Windows.Forms.AxHost+InvalidActiveXStateException的异常 在wpf中封装Com组件时,调用组件 ...
- 用户控件的设计要点 System.Windows.Forms.UserControl
用户控件的设计要点 最近的项目中有一个瀑布图(彩图)的功能,就是把空间和时间上的点量值以图的形式呈现出来,如下图: X坐标为空间,水平方向的一个像素代表一个空间单位(例如50米) Y坐标为时间,垂直方 ...
- System.Windows.Forms.Timer与System.Timers.Timer的区别(zz)
.NET Framework里面提供了三种Timer: System.Windows.Forms.Timer System.Timers.Timer System.Threading.Timer VS ...
随机推荐
- java导入导出下载Excel,xls文件(带下拉框)
/** * 导入excel文件 * 2014-7-23 * @return */ @RequiresPermissions("plug:product:caiwu:upload") ...
- 代码实现:有n个人围成一圈,顺序排号。从第一个人开始报数(从1到3报数),凡报到3的人退出圈子,问最后留下的是原来第几号的那位。
import java.util.ArrayList; import java.util.List; import java.util.Scanner; //有n个人围成一圈,顺序排号.从第一个人开始 ...
- flutter 添加全局环境变量
flutter安装好了之后 要添加全局环境变量才可以在终端通过flutter命令来操作 安装flutter环境变量 vim ~/.bash_profile (不存在就创建,添加下面一行命令) expo ...
- MEF引起的内存泄露
也许你编程的时候很小心,注意不引起内存泄露,例如不要被全局Static的变量引用上,注意Singleton的static引用,注意Event Handler注销,注意IDisposable接口实现,而 ...
- Redis 入门 3.3 散列类型
3.3.1 介绍 散列类型(hash)的键值也是一种字典结构,其储存了字段(field)和字段值的映射,但字段值只能是字符串,不支持其他数据类型,换句话说,散列类型不能嵌套其他的数据类型.一个散列 ...
- python基础学习笔记-切片难点
numbers = [1,2,3,4,5,6,7,8,9,10] print(numbers[5::-2]) print(numbers[10:5:-2]) print(numbers[:5:-2]) ...
- JSON中文处理类实例
$array = array( 'Name'=>'络恩', 'Age'=>24); $post=my_json_encode($array); // 这个函数是判断版本,如果是搞版本的则直 ...
- Oracle 查看 impdp 正在执行的内容
1. 今天进行数据库备份恢复 一直卡住 找了一下 公司另外一个部门的方神提供了一个方法连查看 具体在做什么操作: 2. 现象. impdp 到一个地方直接卡住不动 具体位置 view 这个地方足足卡 ...
- .Net Core IIS下无Log4Net日志输出,命令行下却有(dotnet运行)
.Net Core IIS下无Log4Net日志输出,命令行下却有(dotnet运行) 遇到个诡异的问题,项目发布并寄宿到 IIS上后,Log4Net没有日志输出 1.原因分析 这不应该啊,所有的配置 ...
- java实现整数计算器
计算器代码 package stack; import java.util.ArrayList; import java.util.List; import java.util.Scanner; im ...