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 ...
随机推荐
- 《ASP.NET MVC 5 破境之道》:第一境 ASP.Net MVC5项目初探 — 第三节:View层简单改造
第一境 ASP.Net MVC5项目初探 — 第三节:View层简单改造 MVC默认模板的视觉设计从MVC1到MVC3都没有改变,比较陈旧了:在MVC4中做了升级,好看些,在不同的分辨率下,也能工作得 ...
- 如何将Spring Boot项目打包部署到外部Tomcat
1.项目打包 项目开发结束后,需要打包部署到外部服务器的Tomcat上,主要有几种方式. (1)生成jar包 cd 项目跟目录(和pom.xml同级)mvn clean package## 或 ...
- 基于GitLab与Git Extensions搭建版本控制工具
1.背景 大家知道GitHub是现在非常流行的代码托管工具,但是如果有些项目不想开源的话,则需要付费,因此萌生了自己搭建一个Git的版本控制工具,供内网使用.GitLab则是个好的选择,但是GitLa ...
- VC API常用函数简单例子大全(1-89)
第一个:FindWindow根据窗口类名或窗口标题名来获得窗口的句柄,该函数返回窗口的句柄 函数的定义:HWND WINAPI FindWindow(LPCSTR lpClassName ,LPCST ...
- 网络请求 get 请求时, 如果参数中的字符带有+号
网络请求 get 请求时, 如果参数中的字符带有+号, 今天前端在调用我的API时, 发现有个参数一直没法通过我后台的验证, 但是在前端查看时, 该参数结构又没有什么异常, 又是一番查找, 直到在后端 ...
- 四,php异常处理
1,异常处理 异常处理用于在指定的异常或错误发生时,改变脚本的正常执行流程. <?php try{ //错误或异常 }catch (Exception $ex){ //处理异常 //抛出异常 } ...
- 网站引入外部js
有时想看某个网站下一些数据,需要用到js做一个实时的筛选,却又苦于该网站没用jQuery导致想使用jQuery时,还无法下手,那么下面这段js或许可以帮助你.1.打开我们的chrome调试工具,切换到 ...
- Java并发编程之happens-before
happens-before是JMM最核心的概念,理解happens-before是理解JMM的关键. 一.JMM的设计 首先,让我们先分析一下JMM的设计意图.从JMM的设计者的角度,在设计JMM的 ...
- [Other] 应用下载网站的APK/IPA等常见MIME设置
类型 扩展名 mime 错误做法 安卓安装包 .apk application/vnd.android.package-archive application/vnd.android 苹果安装包 .i ...
- jvm高级特性(6)(线程的种类,调度,状态,安全程度,实现安全的方法,同步种类,锁优化,锁种类)
JVM高级特性与实践(十三):线程实现 与 Java线程调度 JVM高级特性与实践(十四):线程安全 与 锁优化 一. 线程的实现 线程其实是比进程更轻量级的调度执行单位. 线程的引入,可以把一个检查 ...