c# 实时刷新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(参数){实现}。