简单的C#线程开发实例(隔一秒改变一下Label的Text)

更新时间:2023-07-14 02:30:56 阅读: 评论:0

简单的C#线程开发实例(隔⼀秒改变⼀下Label的Text)
要实现的效果:点击按纽,窗⼝上的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 nder, 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 nder, EventArgs e){label1.Text = "0";}
private void button1_Click(object nder, EventArgs e)
    {
      for(int i=0;i<101;i++){label1.Text = i.ToString();}
    }
ppt转pdf  }
}
运⾏⼀下,点击⼀下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 nder, EventArgs e){label1.Text = "0";}
private void run() {    for(int i=0;i<101;i++){        label1.Text = i.ToString();    } }
private void button1_Click(object nder, 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 nder, EventArgs e){label1.Text = "0";}
    private void run()
    {
      i = 0;
      timer1.Interval = 1000; //设置timer1的间隔时间
      timer1.Start(); //启动timer1
    }
    private void timer1_Tick(object nder, EventArgs e)
          {
              i++;
      if (i > 100) {timer1.Stop();}
      label1.Text = i.ToString();
    }
private void button1_Click(object nder, 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 nder, 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 nder, EventArgs e){label1.Text = "0";}
    private void button1_Click(object nder, 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 nder, 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 t_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 nder, EventArgs e){label1.Text = "0";}势利小人
private void button1_Click(object nder, EventArgs e){run();    //调⽤run函数}
private void run(){for(int i=0;i<101;i++){t_lableText( i.ToString() );}}
private void t_lableText(string s){label1.Text = s;}
  }
}
实现的功能与第三个实例是⼀样的,只是,增加了⼀个函数。
写人作文四百字到这⾥,需要了解⼀下委托这个东西,我们就需要委托主线程调⽤函数t_lableText(string s);来改变lable1的值。
⾸先声明⼀个委托: delegate void t_Text(string s);
创建⼀个全局委托变量: t_Text Set_Text;
进⾏实例化: Set_Text = new t_Text(t_lableText); //括号内的t_lableText是委托要调⽤的函数(也就是例6写的t_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 t_Text(string s); //定义委托
  t_Text Set_Text; //定义委托变更
  public Form1(){InitializeComponent();}
  private void Form1_Load(object nder, EventArgs e){label1.Text = "0";      Set_Text = new t_Text(t_lableText); //实例化}  private void button1_Click(object nder, EventArgs e){thread1 = new Thread(new ThreadStart(run));      thread1.Start();}  private void t_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 nder, FormClosingEventArgs e)
     {
        if (thread1.IsAlive) //判断thread1是否存在,不能撤消⼀个不存在的线程,否则会引发异常        {thread1.Abort(); //撤消thread1}
          }
    }
}
这样,⼀个简单的多线程程序就算完成了。

本文发布于:2023-07-14 02:30:56,感谢您对本站的认可!

本文链接:https://www.wtabcd.cn/fanwen/fan/82/1095345.html

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。

标签:线程   委托   函数
相关文章
留言与评论(共有 0 条评论)
   
验证码:
推荐文章
排行榜
Copyright ©2019-2022 Comsenz Inc.Powered by © 专利检索| 网站地图