首先将以下代码放到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. 编译Bootstrap,定制自己的模板

    完全不懂LESS,也懒的去学习它,凭多年的经验,感觉也不用专门花时间去学习了.反正它应该是很成熟的,能执行即可.我用的是WIN7,为了定制颜色等各种特性,需要重新编译Bootstrap.在网上到处中, ...

  2. wpf ,只能窗口调整高度,并且设定最小值。

    MaxWidth="900" WindowStyle="ToolWindow" ResizeMode="CanResize" WindowS ...

  3. selenium下拉框踩坑埋坑

    本文来自网易云社区 作者:王利蓉 最近web端全站重构,所有的页面都大大小小都有些变动,UI就全军覆没了,用例从登录改,改到个人信息页面发现根以前的实现方式完全不一样,这可怎么解决 1.以前的实现(o ...

  4. python+pcap+dpkt 抓包小实例

    #!/usr/bin/env python # -*- coding: utf-8 -*- """ 网络数据包捕获与分析程序 """ imp ...

  5. Debug Dart at External Terminal

    launch.json { // Use IntelliSense to learn about possible attributes. // Hover to view descriptions ...

  6. Console命令,让js调试更简单

    一.显示信息的命令 console.log("normal"); // 用于输出普通信息 console.info("information"); // 用于输 ...

  7. Two Pointers-349. Intersection of Two Arrays

    Given two arrays, write a function to compute their intersection. Example:Given nums1 = [1, 2, 2, 1] ...

  8. 【wireshark】插件开发(三):Lua插件 Dissector

    // TODO: 部分内容需要修改 1. 骨架 首先新建一个文件,命名为foo.lua,注意此文件的编码方式不能是带BOM的UTF8,否则wireshark加载它时会出错(不识别BOM): -- @b ...

  9. 解决 ArchLinux 下中文 Chinese 不能输入 couldnt input 的问题

    解决 ArchLinux 下中文 Chinese 不能输入 couldnt input 的问题 一.Question 一年多的 ArchLinux 用户再次回归.然鹅,见面礼就是终端不能输入中文. 在 ...

  10. struts+spring+hibernate两张表字段名一样处理方法

    在利用struts2+spring+hibernate(利用Hibernate进行分页查询)三大框架进行开发项目的时候,出现一个问题:居然要进行关联查询的十几张表中有两张表的字段一样,并且这两张表中的 ...