首先将以下代码放到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. 如何连接MSSQLSERVER2014(其他版本数据库大体相同)

    购买了服务器后我在上面安装了SqlServer2014,但是程序中总是远程连接不上,特此记录一下: 一.一些基本设置如下链接: 转载自:https://blog.sun0816.com/20381.h ...

  2. 先装VS2008之后,又装了2013,然后启动VS2008提示“Tools Version”有问题?

    这个网上资料一搜很多,我就是按照下面这个链接去解决的,删除 “14.0” 整个键值文件夹之后重启VS2008就好了, 注意:上面第一张图是我在网上找的08和10版本弹出的错误,我自己弹出的是提示14. ...

  3. 网易云首席安全架构师谈安全新形势:DDOS两三天,游戏玩家数从几万降到几百

    本文由  网易云发布. 安全是一个永恒的话题,在业务不断云化.攻击越来越复杂的当下,互联网安全呈现了出什么样的严峻形势?对这些形势,网易云又是如何应对的? 网易云首席安全架构师沈明星 4月13日,网易 ...

  4. FFmpeg编写的代码

    //初始化解封装    av_register_all();    avformat_network_init();    avcodec_register_all();    //封装文件的上下文  ...

  5. IDEA批量修改变量名操作

    批量修改变量名操作:shift+F6选中变量---->修改变量---->Enter回车

  6. 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 ...

  7. poj2488 A Knight's Journey

    http://poj.org/problem?id=2488 题目大意:骑士厌倦了一遍又一遍地看到同样的黑白方块,于是决定去旅行. 世界各地.当一个骑士移动时,他走的是“日”字.骑士的世界是他赖以生存 ...

  8. centos7在分区上建立文件系统和挂载

    在上一篇博客中,我们只说了硬盘的分区,既然进行分区,那么我们就要知道如何使用这些分区,就是接下来的建立文件系统和挂载. mkfs(make filesystem)格式化,建立文件系统 可以看到各种文件 ...

  9. postgresql分区表探索(pg_pathman)

    使用场景 许多系统在在使用几年之后数据量不断膨胀,这个时候单表数据量超过2000w+,数据库的查询也越来越慢,而随着时间的推移许多历史数据的重要性可能逐渐下降.这时候就可以考虑使用分区表来将冷热数据分 ...

  10. vue2.0函数(箭头函数)的this作用域

    在做vue项目时用到了axios,但是发现axios请求之后的回调函数里this并不指向当前vue实例,从而导致浏览器报错. 出错代码及结果: created : function(){ axios. ...