首先将以下代码放到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()和多线程的更多相关文章

  1. Application.DoEvents()的使用

    最近做了一个个人数字图书馆管理系统,因为牵扯到电脑文件的扫描,想做一个实时显示当前扫面文件的功能,就类似于360文件扫描时的效果,本来打算用多线程来实现,但是方法太多没有实现,后来在程序中进行控制,由 ...

  2. C#经典之Application.DoEvents()的使用

    最近做了一个文件上传的模块,因为牵扯到电脑文件的扫描,想做一个实时显示当前扫面文件的功能,就类似于360文件扫描时的效果,本来打算用多线程来实现,但是方法太多没有实现,后来在程序中进行控制,由于文件太 ...

  3. Self-Host c#学习笔记之Application.DoEvents应用 不用IIS也能執行ASP.NET Web API

    Self-Host   寄宿Web API 不一定需要IIS 的支持,我们可以采用Self Host 的方式使用任意类型的应用程序(控制台.Windows Forms 应用.WPF 应用甚至是Wind ...

  4. 关于Application.DoEvents()==转

    记得第一次使用Application.DoEvents()是为了在加载大量数据时能够有一个数据加载的提示,不至于系统出现假死的现象,当时也没有深入的去研究他的原理是怎样的,结果在很多地方都用上了App ...

  5. c#学习笔记之Application.DoEvents应用

    Visual Studio里的摘要:处理当前在消息队列中的所有 Windows 消息. 交出CPU控制权,让系统可以处理队列中的所有Windows消息 比如在大运算量循环内,加Application. ...

  6. C#中Application.DoEvents()的作用

    Visual Studio里的摘要:处理当前在消息队列中的所有 Windows 消息. 交出CPU控制权,让系统可以处理队列中的所有Windows消息,比如在大运算量循环内,加Application. ...

  7. (转).net Application.DoEvents()的作用

    原文地址:http://blog.csdn.net/weinierbian/article/details/6231589 Application.DoEvents()的作用:处理所有的当前在消息队列 ...

  8. Application.DoEvents()

    今天,在按照书上的一个winform例子做练习(实则就是边看边抄了一遍...)的时候,看到Application.DoEvents()这个方法,但是并不明白这个方法是做什么用的.只知道不用这个方法的话 ...

  9. Application.DoEvents()的作用

    记得第一次使用Application.DoEvents()是为了在加载大量数据时能够有一个数据加载的提示,不至于系统出现假死的现象,当时也没有深入的去研究他的原理是怎样的,结果在很多地方都用上了App ...

随机推荐

  1. 887. Super Egg Drop

    You are given K eggs, and you have access to a building with N floors from 1 to N. Each egg is ident ...

  2. Windows下的Nginx安装与配置(PHP)

    因为一直用Apache作为服务器,对Apache的使用和配置已经相对熟悉,今天换了一下nginx的服务器,整个配置流程相对比较简单,php的配置没有任何变化. 主要的参考文档为 http://blog ...

  3. maven项目发布到tomcat后没有lib目录解决方案

    maven项目放入tomcat中时,总是报错,而且这些jar都是真实存在的,错误如下: maven eclipse tomcat java.lang.ClassNotFoundException: o ...

  4. SQL 必知必会 总结(一)

    SQL必知必会 总结(一) 第 1 课 了解SQL 1.数据库(database): 保存有组织的数据容器(通常是一个文件或一组文件). 2.数据库管理系统(DBMS): 数据库软件,数据库是通过 D ...

  5. 自己实现简单的RSA秘钥生成与加解密(Java )

    最近在学习PKI,顺便接触了一些加密算法.对RSA着重研究了一下,自己也写了一个简单的实现RSA算法的Demo,包括公.私钥生成,加解密的实现.虽然比较简单,但是也大概囊括了RSA加解密的核心思想与流 ...

  6. POJ 1154

    #include<iostream> #include<stdio.h> #define MAXN 20 using namespace std; int DFS(int i, ...

  7. web.xml详细配置

    1.启动一个WEB项目的时候,WEB容器会去读取它的配置文件web.xml,读取<listener>和<context-param>两个结点. 2.紧急着,容创建一个Servl ...

  8. 前端必备:FastStoneCapture 和 Licecap &&& mingw c++ 编译执行

    端必备:FastStoneCapture 和 Licecap FastStoneCapture这个软件非常小,只有2M多,并且其功能很强大,包括截图,录制视频,量尺,取色等等,对于前端工程师绝对是必备 ...

  9. Spring Security构建Rest服务-1204-Spring Security OAuth开发APP认证框架之Token处理

    token处理之一基本参数配置 处理token时间.存储策略,客户端配置等 以前的都是spring security oauth默认的token生成策略,token默认在org.springframe ...

  10. java数据结构之三叉链表示的二叉树

    三叉链表示的二叉树定义所畏的三叉链表示是指二叉树由指向左孩子结点.右孩子结点.父亲结点[三叉]的引用(指针)数据和数据组成.    package datastructure.tree.btree; ...