C# backgroundworker 循环更改标签文本

C# backgroundworker loop change label text

我的表单中有一个 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);
    }
}

而是使用 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();
    }
}

停止是因为您 运行 进入 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 线程上执行,因此不需要任何调用。

但总的来说这个想法仍然成立,如果你想从一个不同于创建它的线程操作一个控件,那么你需要调用!