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 ...
随机推荐
- 使用.NET Core 2.1的Azure WebJobs
WebJobs不是Azure和.NET中的新事物. Visual Studio 2017中甚至还有一个默认的Azure WebJob模板,用于完整的.NET Framework. 但是,Visual ...
- WPF制作表示透明区域的马赛克画刷
最近在用WPF制作一款软件,需要像ps一样表示透明区域,于是制作了一个马赛克背景的style.实现比较简单,那么过程和思路就不表了,直接上代码 <DrawingBrush TileMode=&q ...
- 网易云安全DDoS高防全新上线 ,游戏防护实力领先
本文由 网易云发布. 10月24日,网易云安全(易盾)正式上线DDoS高防解决方案[点击查看].基于网易20年网络安全防护经验,网易云安全(易盾)DDoS高防可提供1T超大防护带宽,拥有 ...
- IPv6 Scapy Samples
IPv6 ICMP icmp ipv6 request i=IPv6() i.dst="2001:db8:dead::1" q=ICMPv6EchoRequest() p=(i/q ...
- 极大提高Web开发效率的8个工具和建议(含教程)
面对复杂的 Web 应用的开发,良好的流程和工具支持是必不可少的,它们可以让日常的开发工作更加顺畅.更加高效.本文介绍了6个Web开发利器以及相关的教程,帮助你在开发.调试.集成和发布过程极大地提高效 ...
- C/C++ 语言 Hello world
#include <stdio.h> void main() { int x,i; ; scanf("%d",&x); if(x>y) printf(&q ...
- poj1681 Painter's Problem(高斯消元法,染色问题)
题意: 一个n*n 的木板 ,每个格子 都 可以 染成 白色和黄色,( 一旦我们对也个格子染色 ,他的上下左右都将改变颜色): 给定一个初始状态 , 求将 所有的 格子 染成黄色 最少需要染几次? ...
- strlen()与mb_strlen()的区别
1,strlen()是php的内置函数,可以在php中直接调用:mb_strlen()是php的扩展,需要配置php.ini,以开启mb_strlen()扩展.在php.ini中加载了php_mbst ...
- Youke365_2_4 一处Sql注入漏洞以及一处任意文件删除
本文作者:X_Al3r Prat 0 自白 每一天都是新的一天.没啥吐槽的,步入正题 /system/category.php 文件一处Sql注入## 80-87行代码 $root_i ...
- WebDriverAPI(1)
访问某网页地址 被测网址http:http://www.baidu.com Java语言版本的API实例代码 方法一: @Test public void visitURL(){ String bas ...