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 ...
随机推荐
- C#基础复习(2) 之 装箱拆箱
参考资料 [1] @只增笑耳Jason的回答 https://www.zhihu.com/question/57208269 [2] <C# 捷径教程> 疑难解答 装箱和拆箱是什么? 何时 ...
- 安装docker ce版
可参考 菜鸟教程:http://www.runoob.com/docker/centos-docker-install.html 官网教程:https://docs.docker.com/instal ...
- XCode - 无法对iPhone真机调试的解决方法!
OSX:10.14 XCode:10.1 真机:iPhone 4S 错误很多啊,并非编译错误,编译已经成功了,但是无法安装到真机,我真不理解啊!!由于真的没有想到能够解决,有的错误没有截图,先看部分错 ...
- Windows搭建Nexus3私服
1. Nexus 简介 Nexus 是一个强大的 Maven 仓库管理器 , 它极大地简化了自己内部仓库的维护和外部仓库的访问 ; 利用 Nexus 你可以只在一个地方就能够完全控制访问和部署在你所维 ...
- 配置阿里云ESC服务器部署项目
第一次SSH登录 ECS 服务器: 打开命令行终端(git),键入: > ssh root@39.108.54.110 输入实例密码,进入服务器环境. 配置 root 及应用账号权限 新增管理员 ...
- python Udp与Tcp
一.UDP 首先导入socket 1.客户端 1.创建套接字(socket)udp_socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)2 ...
- RSA的JAVA实现 及javax.crypto.IllegalBlockSizeException
一.背景 最近工作中涉及到RSA加密的相关需求任务,之前对加密算法了解不多,开发过程中遇到了一些坑记录一下. 二.RSA原理 RSA加密是非对称加密,公开私钥,保留私钥.通信时数据通过公开的公钥加密, ...
- Numpy学习50例
基础部分 1.导入numpy模块 import numpy as np 2.查看numpy版本信息 print(np.__version__) numpy的主要对象的多维数组Ndarray.Numpy ...
- 【pkuwc2018】 【loj2537】 Minmax DP+线段树合并
今年年初的时候参加了PKUWC,结果当时这一题想了快$2h$都没有想出来.... 哇我太菜啦.... 昨天突然去搜了下哪里有题,发现$loj$上有于是就去做了下. 结果第一题我5分钟就把所有细节都想好 ...
- 【bzoj2961】共点圆 k-d树
更新:此题我的代码设置eps=1e-8会WA,现在改为1e-9貌似T了 此题网上的大部分做法是cdq分治+凸包,然而我觉得太烦了,于是自己口胡了一个k-d树做法: 加入一个圆$(x,y)$,直接在k- ...