Application.DoEvents()和多线程
首先将以下代码放到Button事件里面:
private void btnStart_Click(object sender, EventArgs e)
{
for (int q = 0; q < 100000; q++)
{
textBox1.Text = q.ToString();
}
}
你会发现当点击Start按钮后,循环会一直进行,此时窗体会出现假死的状态,如:无法拖动。直到循环结束,textBox1中才会显示出结果。如何解决窗体的假死状态??
修改以上代码如下:
private void btnStart_Click(object sender, EventArgs e)
{
for (int q = 0; q < 100000; q++)
{
textBox1.Text = q.ToString();
//实时响应文本框中的值
Application.DoEvents();
}
}
此时再次点击Start按钮后,textBox中的数字会不断改变,同时,你也可以拖动窗体。。。

但是这样使用Application.DoEvents()好吗?如果用多线程来实现相同的效果呢?
多线程实现代码如下:
public Form1()
{
InitializeComponent();
//不捕获跨线程调用引起的异常
CheckForIllegalCrossThreadCalls = false;
}
private void btnStart_Click(object sender, EventArgs e)
{
Thread s1 = new Thread(new ThreadStart(ThreadMeth));
s1.Start();
}
public void ThreadMeth()
{
for (int q = 0; q < 100000; q++)
{
textBox1.Text = q.ToString();
}
}
注意:Form1()里面添加了一行代码,解决跨线程调用产生的异常。
以上代码和使用Application.DoEvents()达到相同的效果。
下面我们来比较一下,使用Application.DoEvents()和使用多线程哪个更耗时?
代码如下:
public void ThreadMeth()
{
label1.Text = DateTime.Now.ToString();
for (int q = 0; q < 100000; q++)
{
textBox1.Text = q.ToString();
}
label5.Text = DateTime.Now.ToString();
}
private void btnStartDo_Click(object sender, EventArgs e)
{
label3.Text = DateTime.Now.ToString();
for (int q = 0; q < 100000; q++)
{
textBox2.Text = q.ToString();
Application.DoEvents();//实时响应文本框中的值
}
label6.Text = DateTime.Now.ToString();
}

(假设以上比较时间的代码处在正确的位置)由此可知,Application.DoEvents()消耗的时间更少,但这里并不建议使用Application.DoEvents(),因为它会引起很多未知的错误。
补充:由于显示的定义 CheckForIllegalCrossThreadCalls = false;并不是好的方法,下面来改进一下,如下:
int i;
private void btnStart_Click(object sender, EventArgs e)
{
Thread s1 = new Thread(new ThreadStart(ThreadMeth));
s1.Start();
}
private void ThreadMeth()
{
for ( i = 0; i < 100000; i++)
{
MethodInvoker mi = new MethodInvoker(Count);
this.Invoke(mi);
//BeginInvoke(mi);
}
}
private void Count()
{
textBox1.Text = i.ToString();
}
MethodInvoker实质上是一个委托,查看其定义可知...
using System;
namespace System.Windows.Forms
{
// 表示一个委托,该委托可执行托管代码中声明为 void 且不接受任何参数的任何方法。
public delegate void MethodInvoker();
}
以上用匿名委托的方式似乎更简洁,代码如下:
private void btnStart_Click(object sender, EventArgs e)
{
new Thread((ThreadStart)(delegate()
{
for (int i = 0; i < 10000; i++)
{
label1.Invoke((MethodInvoker)delegate()
{
textBox1.Text = i.ToString();
});
};
})) .Start();
}
在次线程上计算,在主线程上调用label。
Application.DoEvents()和多线程的更多相关文章
- Application.DoEvents()的使用
最近做了一个个人数字图书馆管理系统,因为牵扯到电脑文件的扫描,想做一个实时显示当前扫面文件的功能,就类似于360文件扫描时的效果,本来打算用多线程来实现,但是方法太多没有实现,后来在程序中进行控制,由 ...
- C#经典之Application.DoEvents()的使用
最近做了一个文件上传的模块,因为牵扯到电脑文件的扫描,想做一个实时显示当前扫面文件的功能,就类似于360文件扫描时的效果,本来打算用多线程来实现,但是方法太多没有实现,后来在程序中进行控制,由于文件太 ...
- Self-Host c#学习笔记之Application.DoEvents应用 不用IIS也能執行ASP.NET Web API
Self-Host 寄宿Web API 不一定需要IIS 的支持,我们可以采用Self Host 的方式使用任意类型的应用程序(控制台.Windows Forms 应用.WPF 应用甚至是Wind ...
- 关于Application.DoEvents()==转
记得第一次使用Application.DoEvents()是为了在加载大量数据时能够有一个数据加载的提示,不至于系统出现假死的现象,当时也没有深入的去研究他的原理是怎样的,结果在很多地方都用上了App ...
- c#学习笔记之Application.DoEvents应用
Visual Studio里的摘要:处理当前在消息队列中的所有 Windows 消息. 交出CPU控制权,让系统可以处理队列中的所有Windows消息 比如在大运算量循环内,加Application. ...
- C#中Application.DoEvents()的作用
Visual Studio里的摘要:处理当前在消息队列中的所有 Windows 消息. 交出CPU控制权,让系统可以处理队列中的所有Windows消息,比如在大运算量循环内,加Application. ...
- (转).net Application.DoEvents()的作用
原文地址:http://blog.csdn.net/weinierbian/article/details/6231589 Application.DoEvents()的作用:处理所有的当前在消息队列 ...
- Application.DoEvents()
今天,在按照书上的一个winform例子做练习(实则就是边看边抄了一遍...)的时候,看到Application.DoEvents()这个方法,但是并不明白这个方法是做什么用的.只知道不用这个方法的话 ...
- Application.DoEvents()的作用
记得第一次使用Application.DoEvents()是为了在加载大量数据时能够有一个数据加载的提示,不至于系统出现假死的现象,当时也没有深入的去研究他的原理是怎样的,结果在很多地方都用上了App ...
随机推荐
- 如何连接MSSQLSERVER2014(其他版本数据库大体相同)
购买了服务器后我在上面安装了SqlServer2014,但是程序中总是远程连接不上,特此记录一下: 一.一些基本设置如下链接: 转载自:https://blog.sun0816.com/20381.h ...
- 先装VS2008之后,又装了2013,然后启动VS2008提示“Tools Version”有问题?
这个网上资料一搜很多,我就是按照下面这个链接去解决的,删除 “14.0” 整个键值文件夹之后重启VS2008就好了, 注意:上面第一张图是我在网上找的08和10版本弹出的错误,我自己弹出的是提示14. ...
- 网易云首席安全架构师谈安全新形势:DDOS两三天,游戏玩家数从几万降到几百
本文由 网易云发布. 安全是一个永恒的话题,在业务不断云化.攻击越来越复杂的当下,互联网安全呈现了出什么样的严峻形势?对这些形势,网易云又是如何应对的? 网易云首席安全架构师沈明星 4月13日,网易 ...
- FFmpeg编写的代码
//初始化解封装 av_register_all(); avformat_network_init(); avcodec_register_all(); //封装文件的上下文 ...
- IDEA批量修改变量名操作
批量修改变量名操作:shift+F6选中变量---->修改变量---->Enter回车
- Educational Codeforces Round 34 (Rated for Div. 2) D - Almost Difference(高精度)
D. Almost Difference Let's denote a function You are given an array a consisting of n integers. You ...
- poj2488 A Knight's Journey
http://poj.org/problem?id=2488 题目大意:骑士厌倦了一遍又一遍地看到同样的黑白方块,于是决定去旅行. 世界各地.当一个骑士移动时,他走的是“日”字.骑士的世界是他赖以生存 ...
- centos7在分区上建立文件系统和挂载
在上一篇博客中,我们只说了硬盘的分区,既然进行分区,那么我们就要知道如何使用这些分区,就是接下来的建立文件系统和挂载. mkfs(make filesystem)格式化,建立文件系统 可以看到各种文件 ...
- postgresql分区表探索(pg_pathman)
使用场景 许多系统在在使用几年之后数据量不断膨胀,这个时候单表数据量超过2000w+,数据库的查询也越来越慢,而随着时间的推移许多历史数据的重要性可能逐渐下降.这时候就可以考虑使用分区表来将冷热数据分 ...
- vue2.0函数(箭头函数)的this作用域
在做vue项目时用到了axios,但是发现axios请求之后的回调函数里this并不指向当前vue实例,从而导致浏览器报错. 出错代码及结果: created : function(){ axios. ...