要实现的效果:点击按纽,窗口上的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. Umbraco(2) - Creating Your First Template and Content Node(翻译文档)

    创建(编辑)你的第一个模板(Template) 展开 Settings > Templates文件夹 - 然后你应该看到子节点名为"Homepage" - 这是我们在创建Do ...

  2. 在Eclipse中导入文件和文件夹

    一. 将JAVA文件夹导入Eclipse中的方法: 方法一:直接将java文件夹复制,然后粘贴到项目下: 方法二:(1)打开Eclipse,点击项目的空白处,现在import: (2)现在Existi ...

  3. CefSharp 发布后在客户机上报找不到dll的问题

    两个因素:一是与项目平台属性的选择要一致二是需要安装CefSharp对应的的VC++可发行组件包(用包管理器引用了此DLL后,会有一个readme.txt,上面详细介绍了CefSharp所需要的环境要 ...

  4. Android异步下载网络图片

    最近新做的一个项目,里面需要下载网络上的图片,并显示在UI界面上,学Android有个常识,就是Android中在主线程中没法直接更新UI的,要想更新UI必须另外开启一个线程来实现,当开启的线程完成图 ...

  5. 未能找到任何适合于指定的区域性或非特定区域性的资源。请确保在编译时已将“xxx.Resources.resources”正确嵌入或链接到程序集

    今天在测试一个工程的时候,突然遇到了这样一个问题: 错误信息:System.Resources.MissingManifestResourceException: 未能找到任何适合于指定的区域或非特定 ...

  6. 001.android初级篇之ToolBar

    官方的最新support library v7中提供了新的组件ToolBar,用来替代之前的ActionBar,实现更为弹性的设计在 material design 也对之做了名称的定义:App ba ...

  7. 第七篇、OC_图片的裁剪基于SDWebImage

    前期有段时间困扰了我很久一个问题由于工程中的图片数据抓取自不同平台,所以图片的大小尺寸不一定,而放置图片的imageView尺寸是一定的,不作任何处理的话会导致图片拉伸变形,因此找了好久解决办法,现把 ...

  8. windows时间同步出错

    http://jingyan.baidu.com/article/fd8044faf1f7ae5030137a7d.html

  9. UI2_UICollectionViewPicture

    // AppDelegate.m // UI2_UICollectionViewPicture // // Created by zhangxueming on 15/7/16. // Copyrig ...

  10. OC4_XML文件解析

    <?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE plist PUBLIC "-// ...