关于多线程的一个例子(UI实时显示)
在开发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应用程序很少,对多线程理解也不是特别深入,有什么不对的地方往大家指正。
[转自]http://www.cnblogs.com/oec2003/archive/2009/12/20/1628412.html
关于多线程的一个例子(UI实时显示)的更多相关文章
- 使用Uploadify实现上传图片生成缩略图例子,实时显示进度条
不了解Uploadify的,先看看前一篇详细说明 http://www.cnblogs.com/XuebinDing/archive/2012/04/26/2470995.html Uploadify ...
- C语言多线程的一个简单例子
多线程的一个简单例子: #include <stdio.h> #include <stdlib.h> #include <string.h> #include &l ...
- Deep Learning 32: 自己写的keras的一个callbacks函数,解决keras中不能在每个epoch实时显示学习速率learning rate的问题
一.问题: keras中不能在每个epoch实时显示学习速率learning rate,从而方便调试,实际上也是为了调试解决这个问题:Deep Learning 31: 不同版本的keras,对同样的 ...
- JavaScript实时显示当前时间的例子
用javascript代码在当前页面中实时显示当前时间.代码如下: <html> <head> <title>JavaScript 实时显示当前时间-www.jbx ...
- 【.net 深呼吸】启动一个进程并实时获取状态信息
地球人和火星人都知道,Process类既可以获取正在运行的进程,也可以启动一个新的进程.在79.77%应用场合,我们只需要让目标进程顺利启动就完事了,至于它执行了啥,有没有出错,啥时候退出就不管了. ...
- UI实时预览最佳实践(转)
UI实时预览最佳实践 概要:Android中实时预览UI和编写UI的各种技巧.本文的例子都可以在结尾处的示例代码中看到并下载.如果喜欢请star,如果觉得有纰漏请提交issue,如果你有更好的点子可以 ...
- ASP.NET 多线程 监控任务执行情况,并显示进度条
关于多线程的基本概念和知识在本文中不多讲,而且我懂的也不是很透,说的太多误人子弟...对于我来说,做本文提到的功能够用就行,等实现其他效果不够用的时候,再深入研究 推荐看园子里的两篇博客应该就有个基本 ...
- Android学习总结——实时显示系统时间
我们都知道System.currentTimeMillis()可以获取系统当前的时间,这里要实时显示就可以开启一个线程,然后通过handler发消息,来实时的更新TextView上显示的系统时间.具体 ...
- android 在你的UI中显示Bitmap - 开发文档翻译
由于本人英文能力实在有限,不足之初敬请谅解 本博客只要没有注明“转”,那么均为原创,转贴请注明本博客链接链接 Displaying Bitmaps in Your UI 在你的UI中显示Bitmap ...
随机推荐
- 【ASP.NET Web API教程】3.2 通过.NET客户端调用Web API(C#)
原文:[ASP.NET Web API教程]3.2 通过.NET客户端调用Web API(C#) 注:本文是[ASP.NET Web API系列教程]的一部分,如果您是第一次看本博客文章,请先看前面的 ...
- cocos2d-x游戏开发系列教程-搭建cocos2d-x的windows开发环境
1.在上一篇中我们成功运行了HelloCpp和TestCpp工程,我们到目录cocos2d-x-2.2.1\Debug.win32下 查看生成的文件,在我电脑上绝对路径是H:\source\cocos ...
- alv 列标题
gs_fieldcat-reptext_ddic才是显示列标题的
- DirectX SDK版本与Visual Studio版本
对于刚刚接触 DirectShow 的人来说,安装配置是一个令人头疼的问题,经常出现的情况是最基本的 baseclass 就无法编译.一开始我也为此费了很大的功夫,比如说修改代码.修改编译选项使其编译 ...
- jquery 拓展方法
摘抄自(http://hi.baidu.com/jjjvzugcpmcdmor/item/0e32a89c36a18544f04215d7) $.fn是指jquery的命名空间,加上fn上的方法及属性 ...
- GCC编译优化指南【作者:金步国】
GCC编译优化指南[作者:金步国] GCC编译优化指南 作者:金步国 版权声明 本文作者是一位自由软件爱好者,所以本文虽然不是软件,但是本着 GPL 的精神发布.任何人都可以自由使用.转载.复制和再分 ...
- 框架学习之道:PE框架简介
1.PE框架开发新功能所需的部分 2.PE框架工作流程(重要) 首先根据<transcation>中的id号,找到模板(template),然后再根据模板找到责任链(chain),一旦确认 ...
- 开源yYmVc项目 v 0.2 版本号介绍
项目地址:https://code.csdn.net/hacke2/yymvc 本版本号主要实现下面几点功能: 1.框架入口基于过滤器统一实现,action后缀动态配置 2.action配置模仿str ...
- SilkTest高级进阶系列6-motif tag
看SilkTest代码的时候不小心看到winclass.inc里面的一些类申明使用的是motif tag,例如: [-] winclass MessageBoxClass : DialogBox [ ...
- 获取CentOS软件源中的updates包
之前在本地网络中建了一个CentOS软件源,挺好用的,可是发现有些软件还是装不上,因为系统安装盘中的包并不全,有些软件的依赖在updates源中,updates源在网上,怎么把其中的包拿到呢?一种方法 ...