要实现的效果:点击按纽,窗口上的label上出现1~100数字的变化。

第一个实例(把窗口上的label上文字改成0):

using System;

using System.Windows.Forms;

namespace ThreadTest

{

   public partial class Form1 : Form

  {

    public Form1(){InitializeComponent();}

           private void Form1_Load(object sender, EventArgs e){label1.Text = "0";}    
  }
}
这个是最简单的实例,很容易。
第二个实例(点击button,循环显示0动态变化到100数字):
using System;
using System.Windows.Forms;
namespace ThreadTest
{    
  public partial class Form1 : Form    
  {        
    public Form1(){InitializeComponent();}
           private void Form1_Load(object sender, EventArgs e){label1.Text = "0";}
           private void button1_Click(object sender, EventArgs e)
    {
      for(int i=0;i<101;i++){label1.Text = i.ToString();}
    }    
  }
}
运行一下,点击一下button1,没有看到0~100动态变化,就直接到了100了。 原因:因为你的处理器速度太快了,就只能看到最后的结果。那么,怎样才能看到中间过程呢?
我们先用函数的方式来实现上面的功能,写个名为run的函数: private void run() {     for(int i=0;i<101;i++){         label1.Text = i.ToString();     } }
这样就可以直接调用run函数实现功能了,而不用在事件函数内写代码。
第三个实例(使用函数):
using System;
using System.Windows.Forms;
namespace ThreadTest
{    
  public partial class Form1 : Form    
  {        
    public Form1(){InitializeComponent();}
           private void Form1_Load(object sender, EventArgs e){label1.Text = "0";}

           private void run() {     for(int i=0;i<101;i++){         label1.Text = i.ToString();     } }   
           private void button1_Click(object sender, EventArgs e){run();} 
   }
}
这里就需要在循环过程中加延时了,假定我们每隔1s的延时,lable1的值增加1,方法有很多。
首先我们用一个timer来实现延时。 添加一个timer, 命名为timer1,在timer1的tick事件内添加语句,改变label1的值。(Tick事件是每经过指定时间间隔后被触发)。
第四个实例(使用timer),实现每隔1s的延时,lable1的值增加1,以达到动态变化的效果:
using System;
using System.Windows.Forms;
namespace ThreadTest
{    
  public partial class Form1 : Form    
  {        
     int i;          //全局变量
          public Form1(){InitializeComponent();}

            private void Form1_Load(object sender, EventArgs e){label1.Text = "0";} 
    private void run()
    {     
      i = 0;     
      timer1.Interval = 1000; //设置timer1的间隔时间    
      timer1.Start(); //启动timer1        
    }
    private void timer1_Tick(object sender, EventArgs e)

          {
               i++;            
       if (i > 100) {timer1.Stop();}            
       label1.Text = i.ToString();        
    }    
            private void button1_Click(object sender, EventArgs e) {run();}
   }
}
我们运行一下,能够看到0~100循环的过程了。
以上是我们平常的做法,让label动态变化的效果,下面我们开始使用线程来实现上面的功能。

由于要使用多线程,我们需要引用using System.Threading;
通过下面的语句就定义一个名为thread1的线程 private Thread thread1;
和定义函数极为相似,定义线程之后,就要进行实例化: thread1 = new Thread(new ThreadStart(run));
这个语句的意思就是实例化thread1并将run函数设定为thread1的入口函数(大概意思就是,让run函数在线程thread1上执行)。
创建线程就算完成了,那么怎么运行线程呢? 其实和启动timer1是类似的,thread1.Start();就运行了我们创建的线程thread1。
既然我们创建了线程,那么在关闭窗口的时候,就要撤消线程。添加FormClosing事件,在事件内部写如撤消线程的代码:

private void Form1_FormClosing(object sender, FormClosingEventArgs e)
{
   if (thread1.IsAlive) //判断thread1是否存在,不能撤消一个不存在的线程,否则会引发异常
   { thread1.Abort(); //撤消thread1 }
}
这样才算大功告成,整理的代码如下:(在第三个实例的基础上加以改动)。
第五个实例:
using System;
using System.Threading;
using System.Windows.Forms;

namespace ThreadTest

{

  public partial class Form1 : Form

   {

      private Thread thread1;

    public Form1(){InitializeComponent();}

    private void Form1_Load(object sender, EventArgs e){label1.Text = "0";}

    private void button1_Click(object sender, EventArgs e){thread1 = new Thread(new ThreadStart(run));thread1.Start();}

    private void run(){for (int i = 0; i < 101; i++){label1.Text = i.ToString();}}

            private void Form1_FormClosing(object sender, FormClosingEventArgs e){if (thread1.IsAlive){thread1.Abort();}}    
  }
}
运行一下,按button1,出错了,怎么回事呢?
看看出错原因,是在run函数内的label1.Text = i.ToString();语句上出的错,没错啊,语法正确啊。解释一下,出错的原因是为了保护数据的安全所以不能跨线程调用控件,而label1.Text = i.ToString();句则是在线程thread1上面调用主线程的控件,肯定会出错的!怎么办呢?用委托啊,我的理解就是,线程thread1不能调用主线程的lable1,所以,就委托主线程来改变lable1的值。 首先看一个例子:(从例3改写)(并不创建线程,仅有主线程) 创建一个函数,用来设置lable1的值;

private void set_lableText(string s) { label1.Text = s; } 当需要改变lable1的值时,就调用它,并传递要改变的值。

第六个实例:

using System;

using System.Windows.Forms;

namespace ThreadTest

{

  public partial class Form1 : Form

  {

    public Form1(){InitializeComponent();}

 private void Form1_Load(object sender, EventArgs e){label1.Text = "0";}

private void button1_Click(object sender, EventArgs e){run();    //调用run函数}

private void run(){for(int i=0;i<101;i++){set_lableText( i.ToString() );}}

           private void set_lableText(string s){label1.Text = s;}    
   }
}
实现的功能与第三个实例是一样的,只是,增加了一个函数。
到这里,需要了解一下委托这个东西,我们就需要委托主线程调用函数set_lableText(string s);来改变lable1的值。

首先声明一个委托: delegate void set_Text(string s);

创建一个全局委托变量: set_Text Set_Text;

进行实例化: Set_Text = new set_Text(set_lableText); //括号内的set_lableText是委托要调用的函数(也就是例6写的set_lableText(string s);函数)

现在,就剩下调用委托了,怎么调用委托呢?很简单。 同过Invoke来调用,语句如下:

label1.Invoke(Set_Text, new object[] { i.ToString() }); //Set_Text是调用的委托,object[]则是我们要传递的参数

整理代码如下,第七个实例:

using System;

using System.Threading;

using System.Windows.Forms;

namespace ThreadTest

{

  public partial class Form1 : Form

  {

      private Thread thread1; //定义线程

  delegate void set_Text(string s); //定义委托

  set_Text Set_Text; //定义委托变更

  public Form1(){InitializeComponent();}

  private void Form1_Load(object sender, EventArgs e){label1.Text = "0";       Set_Text = new set_Text(set_lableText); //实例化}

  private void button1_Click(object sender, EventArgs e){thread1 = new Thread(new ThreadStart(run));       thread1.Start();}

  private void set_lableText(string s){label1.Text = s;}//主线程调用的函数

  private void run()

     {

        for (int i = 0; i < 101; i++)

        {

          label1.Invoke(Set_Text, new object[] { i.ToString() }); //通过调用委托,来改变lable1的值

          Thread.Sleep(1000); //线程休眠时间,单位是ms

        }

      }

           private void Form1_FormClosing(object sender, FormClosingEventArgs e)        
     {            
        if (thread1.IsAlive) //判断thread1是否存在,不能撤消一个不存在的线程,否则会引发异常            
        {thread1.Abort(); //撤消thread1}
           }
    }
}
这样,一个简单的多线程程序就算完成了。

简单的C#线程开发实例(隔一秒改变一下Label的Text)的更多相关文章

  1. C#一个简单的关于线程的实例

    很多初学者听到线程会觉得晦涩难懂,很多资料一堆专有名词也是让人心烦意乱,本着学习加分享的态度,这里做一个简单的实例分享帮助初学者们初识多线程.  首先大概讲述一下多线程和多进程的区别,任务管理器里各种 ...

  2. Hibernate入门2.简单的项目开发实例

    Hibernate入门2.简单的项目开发实例 这一节通过一个简单的项目学习Hibernate项目的配置 代码下载 : 链接: http://pan.baidu.com/s/1zlgjl 密码: p34 ...

  3. WCF揭秘(一)——简单的WCF开发实例

    一.WCF是什么 WCF是微软为了实现各个开发平台之间的无疑缝连接而开发一种崭新工具,它是为分布式处理而开发.WCF将DCOM.Remoting.Web Service.WSE.MSMQ.AJAX服务 ...

  4. c++简单的ATL COM开发和调用实例(转)

    c++简单的ATL COM开发和调用实例 1.打开VS2010,新建ATL COM 项目,步骤:“文件” -->“新建” -->“项目”,选择“Visual C++” -->“ATL ...

  5. 《HTML 5网页开发实例具体解释》样章、内容简单介绍、前言

    http://spu.jd.com/1167757597.html http://product.dangdang.com/23484942.html 样章 http://download.csdn. ...

  6. Android音乐播放器的开发实例

    本文将引导大家做一个音乐播放器,在做这个Android开发实例的过程中,能够帮助大家进一步熟悉和掌握学过的ListView和其他一些组件.为了有更好的学习效果,其中很多功能我们手动实现,例如音乐播放的 ...

  7. 持久化框架Hibernate 开发实例(一)

    1 Hibernate简介 Hibernate框架是一个非常流行的持久化框架,其中在web开发中占据了非常重要的地位, Hibernate作为Web应用的底层,实现了对数据库操作的封装.HIberna ...

  8. 基于线程开发一个FTP服务器

    一,项目题目:基于线程开发一个FTP服务器 二,项目要求: 基本要求: 1.用户加密认证   2.允许同时多用户登录   3.每个用户有自己的家目录 ,且只能访问自己的家目录   4.对用户进行磁盘配 ...

  9. RDIFramework.NET -.NET快速信息化系统开发整合框架 【开发实例 EasyUI】之产品管理(WebForm版)

    RDIFramework.NET—.NET快速开发整合框架 [开发实例]之产品管理(WebForm版) 接上篇:RDIFramework.NET (.NET快速信息化系统开发整合框架) [开发实例]之 ...

随机推荐

  1. poj 1390 动态规划

    思路: 黑书的例题 #include<iostream> #include<cstring> #include<algorithm> #include<cma ...

  2. 转: HHVM at Baidu

    评注: 一个项目迁移的问题考虑与实现使用.非常之详细. 转:http://lamp.baidu.com/2014/11/04/hhvm-in-baidu/ 在这之前我们介绍了我们为什么要迁移PHP到H ...

  3. 【转】同一台机器部署两个jboss方法

    更改jboss的端口信息 1) 更改webservic的端口信息D:\jboss-new\server\default\conf\jboss-service.xml文件 <mbean code= ...

  4. Intent的4种传值方法总结

    xml 代码: <Button     android:id="@+id/button1"     android:layout_width="wrap_conte ...

  5. 在sql设计中没法修改表结构

    在做练习的时候经常表没设计好,后来有要去数据库修改表结构但是没词用界面修改的时候都会提示要保存 转自http://www.57xue.com/ItemView/Sql/2016061600160.ht ...

  6. SQL Server 2000中的完整备份、差异备份操作

    在SQL Server 2000中,假定我们拥有一个数据库为:Test, 现在需要它每天19:00自动进行一次备份,并且以后一旦发生数据库错误,我们都可以通过备份文件将数据库恢复到任何一个备份过的时刻 ...

  7. (转)从集中到分布,解读网络视频IT架构变迁

    2006年以视频网站为代表的网络视频行业迅速崛起,IPTV.视频分享网站.视频搜索网站.提供视频服务的互动社区.交友.播客等等新兴媒体发展迅猛.网络视频行业现已成为众多资本机构关注与投资的焦点.但是在 ...

  8. 8款超绚丽的jQuery焦点图动画

    随着前端技术和浏览器技术的不断发展,人们开始对网页视觉效果的要求越来越高.我们经常会在页面中看到很多炫酷的图片焦点图播放控件,有些甚至是大屏的焦点图占用大片的页面空间,从而吸引用户的眼球.本文要分享的 ...

  9. java synchronized关键字浅探

    synchronized 是 java 多线程编程中用于使线程之间的操作串行化的关键字.这种措施类似于数据库中使用排他锁实现并发控制,但是有所不同的是,数据库中是对数据对象加锁,而 java 则是对将 ...

  10. 常见web服务器错误

    参考地址:http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.4.5     10 Status Code Definitions ...