C#backgroundworker循环更改标签文本

时间:2017-10-25 11:35:41

标签: c# loops backgroundworker

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

2 个答案:

答案 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线程上执行,因此不需要任何调用。

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