要实现的效果:点击按纽,窗口上的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. 剑指Offer10 打印1到最大n位数

    /************************************************************************* > File Name: 10_PrintT ...

  2. 转: 数字证书原理 https 完整过程解析

    点评: 讲的非常的详细与全面,值得一看. 转: http://www.cnblogs.com/JeffreySun/archive/2010/06/24/1627247.html 文中首先解释了加密解 ...

  3. selenium修改控件属性

    起因:在进行退出的时候,控件属性显示为不可显示,于是在界面上是不可以点击的,如果想点击这个按钮,只能通过修改控件属性,进行点击 上图看控件,正常来说,点击坐边的用户名,下拉会出现一个logout,退出 ...

  4. ASP.NET多线程下使用HttpContext.Current

    本来要实现asp.net下使用tcp通讯方式向服务器获取数据,开始采用的方式是 参考: ASP.NET多线程下使用HttpContext.Current为null解决方案 http://www.cnb ...

  5. Oracle数据库作业-3 查询

    1. 查询Student表中的所有记录的Sname.Ssex和Class列.

  6. CSS中如何将li横向排列

    直接贴段例子代码吧: @{ Layout = null;} <!DOCTYPE html><style type="text/css"> .test li ...

  7. jQuery之选择器

    jQuery元素选择器和属性选择器允许您通过标签名.属性名或内容对 HTML 元素进行选择和操作,而在 HTML DOM中,选择器可以对DOM元素组或单个DOM 节点进行操作.通俗点说,选择器的作用就 ...

  8. javascript中ajax post实例详解

    一,原生态的XMLHttpRequest 代码如下 复制代码 <script language="javascript">         function savei ...

  9. Coarse-Grained lock 粗粒度锁

    用一个锁Lock一组相关的对象 有时,需要按组来修改多个对象. 这样,在需要锁住其中一个的时候,必须连带地将其他的对象都上锁. 为每一个对象都加上一个锁是很繁琐的. 粗粒度锁是覆盖多个对象的单个锁. ...

  10. webSphere中文日志乱码,设置日志编码方法

     1:管理控制台--->服务器--->应用程序服务器--->server1--->java和进程管理--->进程定义--->java虚拟机--->将通用jvm ...