实时刷新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

System.Windows.Forms.Timer 用于以用户定义的事件间隔触发事件。 Windows 计时器是为单线程环境设计的,其中,UI 线程用于执行处理。 它要求用户代码有一个可用的 UI 消息泵,而且总是在同一个线程中操作,或者将调用封送到另一个线程。

使用此计时器时,请使用 Tick 事件执行轮询操作,或在指定的时间内显示启动画面。 每当 Enabled 属性设置为 true 且 Interval 属性大于 0 时,将引发 Tick 事件,引发的时间间隔基于 Interval 属性设置。

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

Windows 窗体 Timer 组件是单线程组件,精度限定为 55 毫秒。 如果您需要更高精度的多线程计时器,请使用 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(参数){实现}。

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

posted @ 2013-11-20 09:35  幸运的程序员  阅读(3596)  评论(0编辑  收藏  举报