我的表单中有一个Label
,想要每秒更改一次文本。我认为BackgroundWorker
是我需要的,但其中的while循环似乎不起作用。循环中的第一行完成了它的工作,但在Thread.Sleep
之后,循环似乎停止了。
public MainForm()
{
InitializeComponent();
backgroundWorker1.DoWork += new DoWorkEventHandler(getFrame);
backgroundWorker1.RunWorkerAsync();
}
void getFrame(object sender, DoWorkEventArgs e)
{
while(true) {
ageLabel.Text = "test";
Thread.Sleep(1000);
ageLabel.Text = "baa";
Thread.Sleep(1000);
}
}
答案 0 :(得分:2)
相反,请使用Timer。考虑这个示例,其中label1
是WinForm上的简单Label
控件:
public partial class Form1 : Form
{
Timer _timer = new Timer();
public Form1()
{
InitializeComponent();
_timer.Interval = 1000;
_timer.Tick += _timer_Tick;
_timer.Start();
}
private void _timer_Tick(Object sender, EventArgs e)
{
label1.Text = DateTime.Now.ToString();
}
}
答案 1 :(得分:2)
发生停止是因为您遇到System.InvalidOperationException
异常,因为您尝试从与创建时不同的线程中操纵控制元素。
要解决您的问题,您可以使用Control.BeginInvoke。此方法将在主线程上执行控制操作:
while (true)
{
ageLabel.BeginInvoke(new Action(() => { ageLabel.Text = "test"; }));
Thread.Sleep(1000);
ageLabel.BeginInvoke(new Action(() => { ageLabel.Text = "bla"; }));
Thread.Sleep(1000);
}
如果在visual studio中使用Windows窗体,建议您查看output window。这样的例外将在那里显示。 :)
编辑:如果您只想按时间间隔更新UI组件属性,您也可以使用Timer,它是为此目的而构建的。它在主UI线程上执行,因此不需要任何调用。
但总的来说,这个想法仍然存在,如果你想从一个不同的线程操作一个控件,那么你需要调用!