实时刷新Winform中Label的Text

最直白的例子:

 private void btnStart_Click(object sender, EventArgs e)
        {           
            int i = 0;
            while (i < 60)
            {
                labelTime.Text = i.ToString();
                Thread.Sleep(1000);
            }
        }

运行的时候窗口死在哪里似的,不能动。这是不对的,下面看两种对的方法:

第一种方法:Timer

它要求用户代码有一个可用的 UI 消息泵,而且总是在同一个线程中操作,或者将调用封送到另一个线程。

true 且 Interval 属性大于 0 时,将引发 Tick 事件,引发的时间间隔基于 Interval 属性设置。

此类提供用于设置时间间隔以及启动和停止计时器的方法。

如果您需要更高精度的多线程计时器,请使用 System.Timers 命名空间中的 Timer 类。

private void btnStart_Click(object sender, EventArgs e)
        {
            System.Windows.Forms.Timer timer = new System.Windows.Forms.Timer();
            timer.Interval = 1000;
            timer.Tick += new EventHandler(RefreshTime);
            timer.Enabled = true;
            timer.Start();
        }
       
        private void RefreshTime(object sender, EventArgs e)
        {
            int n = int.Parse(labelTime.Text);
            if (n > 0)
            {
                labelTime.Text = (n - 1).ToString();
            }
            else
            {
                ((System.Windows.Forms.Timer)sender).Stop();
            }
        }

窗口开可以动,还会有反应。

第二种方法:Thread

有时候我们需要创建一个线程,在线程里做这件事情。刷新Label必须由窗体主线程来做,具体做法是在创建的线程里把一个委托交给主线程。

 Thread threadScan;//线程
        long num = 0L;//计数

        private void btnScan_Click(object sender, EventArgs e)
        {
            num = 0L;
            threadScan = new Thread(new ThreadStart(ScanFile));
            threadScan.Start();
        }
//线程触发的方法
 private void ScanFile()
        {
            SetText st = new SetText(UpdateLabel);
            while (num < 10)
            {
                if (labelScan.InvokeRequired)
                {
                    labelScan.Invoke(st, num.ToString());//交给主线程
                }
                else
                {
                    labelScan.Text = num.ToString();
                }
                num++;
                Thread.Sleep(1000);
            }
            threadScan.Abort();
        }
//委托
        public delegate void SetText(string text);
//委托调用的方法
        private void UpdateLabel(string str)
        {
            labelScan.Text = str;
        }

顺便写一个匿名委托的例子

 private void ScanFile()
        {
            while (num < 10)
            {
                if (labelScan.InvokeRequired)
                {
                    SetText st = delegate(string str)
                        {
                            labelScan.Text = str;
                        };
                    labelScan.Invoke(st, num.ToString());
                }
                else
                {
                    labelScan.Text = num.ToString();
                }
                num++;
                Thread.Sleep(1000);
            }
            threadScan.Abort();
        }

不用方法,不用new,对象等于delegate(参数){实现}。

一边自学,一边总结,有不对的地方请不要吝啬拍砖