在开发Window应用程序的时候,经常需要在界面上显示出已经执行到什么步骤了,拿一个简单例子来说,创建一个Winform程序,在窗体上访一个Button和一个Label,点击Button时做100次循环,在Label上实时显示当前循环的次数。一种简单的做法就是使用Application.DoEvents,代码如下:

private void btnTest_Click(object sender, EventArgs e)
{for (int i = 0; i < 100; i++){Thread.Sleep(100);label1.Text = i + "/100";Application.DoEvents();}
}

上面的代码如果将Application.DoEvents();去掉当点击Button时,程序会卡住,直到这个循环执行完成,当这个循环足够大时是不能忍受的。不过小数据量用Application.DoEvents()还行,数据量大了使用Application.DoEvents()就会带来性能的问题。所以Application.DoEvents()要慎用,在大数据量的时候可以使用多线程解决。如下:

private void btnTest_Click(object sender, EventArgs e)
{Thread thread = new Thread(new ThreadStart(DoWork));thread.Start();
}
private void DoWork()
{for (int i = 0; i < 100; i++){Thread.Sleep(100);label1.Text = i + "/100";}
}

嗯?出现异常了是吧,没错上面的代码运行后后会出现“线程间操作无效: 从不是创建控件“label1”的线程访问它。”的异常。关于什么原因造成的,大家可以google一下。不过上面代码在vs03中貌似可以正常运行。将代码改成下面这样就可以正常运行了:

private void btnTest_Click(object sender, EventArgs e)
{Thread thread = new Thread(new ThreadStart(DoWork));thread.Start();
}
private void DoWork()
{for (int i = 0; i < 100; i++){Thread.Sleep(100);this.Invoke(new Action<string>(this.ChangeLabel),i.ToString());}
}
private void ChangeLabel(string i)
{label1.Text = i + "/100";
}

如果嫌多写一个ChangeLabel方法费事,可以写成匿名方法的形式,如下:

private void btnTest_Click(object sender, EventArgs e)
{Thread thread = new Thread(new ThreadStart(DoWork));thread.Start();
}
private void DoWork()
{for (int i = 0; i < 100; i++){Thread.Sleep(100);this.Invoke(new Action(delegate(){label1.Text=i+"/100";}));}
}

同样可以使用匿名方法的方式将DoWork方法也去掉:

private void btnTest_Click(object sender, EventArgs e)
{Thread thread = new Thread(new ThreadStart(delegate() {for (int i = 0; i < 100; i++){Thread.Sleep(100);this.Invoke(new Action(delegate() { label1.Text = i + "/100"; }));}}));thread.Start();
}

如果想传参数到Dowork方法中,那么就不能使用ThreadStart类了,应该使用ParameterizedThreadStart类,如下:

private void btnTest_Click(object sender, EventArgs e)
{string name = "oec2003";Thread thread = new Thread(new ParameterizedThreadStart(DoWork));thread.Start(name);
}
private void DoWork(object name)
{for (int i = 0; i < 100; i++){Thread.Sleep(100);this.Invoke(new Action(delegate(){label1.Text=name+":"+ i+"/100";}));}
}

同样我们也可以使用线程池的方式来实现

private void btnTest_Click(object sender, EventArgs e)
{ThreadPool.QueueUserWorkItem(new WaitCallback(DoWork));
}
private void DoWork(object o)
{for (int i = 0; i < 100; i++){Thread.Sleep(100);this.Invoke(new Action(delegate(){label1.Text=i+"/100";}));}
}

使用匿名方法的方式:

private void btnTest_Click(object sender, EventArgs e)
{ThreadPool.QueueUserWorkItem(new WaitCallback(delegate(object o){for (int i = 0; i < 100; i++){Thread.Sleep(100);this.Invoke(new Action(delegate() { label1.Text = i + "/100"; }));}}));
}

平时做Windows应用程序很少,对多线程理解也不是特别深入,有什么不对的地方往大家指正。

返回开篇(索引)

转载于:https://www.cnblogs.com/oec2003/archive/2009/12/20/1628412.html

关于多线程的一个例子(UI实时显示)相关推荐

  1. 项目实例改编:利用structs2的action 实时显示图片、pdf和其他内容的框架抽取。(转)...

    转自:http://www.verydemo.com/demo_c167_i1382.html 针对:预览文件(图片,PDF)文件来源为action中的inputStream 重点: structs2 ...

  2. QT5完成一个数据实时显示控制的Demo

    使用QT5完成一个数据实时显示控制的Demo TestUiTheme-pro main.cpp mainwindow.h mainwindow.cpp themewidget.h themewidge ...

  3. python串口数据绘图_使用Python串口实时显示数据并绘图的例子

    使用pyserial进行串口传输 一.安装pyserial以及基本用法 在cmd下输入命令pip install pyserial 注:升级pip后会出现 "'E:\Anaconda3\Sc ...

  4. python读取串口数据 绘图_使用Python串口实时显示数据并绘图的例子

    使用pyserial进行串口传输 一.安装pyserial以及基本用法 在cmd下输入命令pip install pyserial 注:升级pip后会出现 "'E:Anaconda3Scri ...

  5. 使用QT5完成一个数据实时显示控制的Demo

    使用QT5完成一个数据实时显示控制的Demo TestUiTheme-pro main.cpp mainwindow.h mainwindow.cpp themewidget.h themewidge ...

  6. python+tkinter+threading制作多线程简易音乐播放器(自动播放,上一曲,下一曲,播放,暂停,实时显示歌曲名并能自动切换歌曲的功能)

    https://blog.csdn.net/qq_41962782/article/details/80106158 小弟是小白因大作业,在此博文的基础上,我增加了歌曲目录的选择,自动播放,实时显示歌 ...

  7. 测试基于STM32的ADIS16405评估板,并在匿名四轴上实时显示3轴陀螺仪+3轴加速度计+3轴磁力计 波形。本文最后还公开一个基于C# 的串口波形显示客户端源码。

    标题:测试基于STM32的ADIS16405评估板,并在匿名四轴上实时显示3轴陀螺仪+3轴加速度计+3轴磁力计 波形.本文最好还公开一个基于C# 的串口波形显示客户端源码. 这里附上该评估板的原理图和 ...

  8. 使用Uploadify实现上传图片生成缩略图例子,实时显示进度条

    不了解Uploadify的,先看看前一篇详细说明 http://www.cnblogs.com/XuebinDing/archive/2012/04/26/2470995.html Uploadify ...

  9. js实现在页面实时显示时间,一个按钮控制时间暂停和开始

    js实现在html实时显示时间,一个按钮控制时间暂停和开始.代码如下: <head><meta charset="UTF-8"><title>& ...

最新文章

  1. Pandas可视化综合指南:手把手从零教你绘制数据图表
  2. 只有一流的人才能干出一流的工作,只有具备大量一流的人才的企业才能成为一流的企业...
  3. Database之SQLSever:SQLSever数据库管理学习并深入理解SQL命令语句进阶综合篇《初级→中级→高级》(持续更新,建议收藏)
  4. PAT甲级题目翻译+答案 AcWing(链表)
  5. eclipse 保存html 提示 save could not be completed
  6. 文件字符输入流的使用 FileReader java
  7. harmonyOS的架构图,HarmonyOS通用设计基础---应用架构
  8. 几个 XmlTextReader 的例子, 帮了我大忙.
  9. 去除DataTable重复数据的三种方法(转)
  10. 平庸程序员的成长笔记
  11. graphpad 中文版使用手册
  12. Tampermonkey油猴脚本安装及入门
  13. 均线颜色怎么区分_均线入门:一图学会区分不同均线的颜色与炒股技巧
  14. POJ-2524 Ubiquitous Religions
  15. python爬虫-抓取内涵吧内涵段子
  16. 转载一份大佬的面试指南,命中率很高
  17. 代理模式(静态代理和动态代理)
  18. c4droid用c语言画爱心,【图片】[自学C语言第五天]发一个作品【c4droid吧】_百度贴吧...
  19. 群星Stellaris for Mac(太空策略游戏)
  20. 计算机软件开发工程师简历,net软件工程师的简历范文

热门文章

  1. 拾遗:『ext4 Quota』
  2. DataGridView加入CheckBox列 (VB)
  3. [导入]毕业的大学生的100条忠告
  4. 如何根据用户IP得到用户所在位置。
  5. 系统进入低功耗的配置
  6. 【拔刀吧少年】之shell数组
  7. c++代码表白_一行 Python 代码能实现什么丧心病狂的功能? | CSDN博文精选
  8. 怎么确定迭代器后面还有至少两个值_为什么range不是迭代器?range到底是什么类型?
  9. iphone以旧换新活动_【武商襄阳购物中心】 参与iphone以旧换新活动,最高可抵4300元,旧机可享10%额外补贴...
  10. 如何实现 OpenAPI 多语言 SDK 开发?