在后台工作程序更改标签文本错误

时间:2015-01-19 13:16:04

标签: c# winforms backgroundworker

我正在尝试在后台工作进程中更改表单上的标签但是它表示未处理的异常。我已经看过这个错误了,它说要像接受的答案那样调用它:Update label text in background worker winforms

我已经成功完成了更改复选框列表中的值,但是我使用了相同的方法,并且对于它不会调用的标签,当我输入时,我在代码中得到红色错误行它

我的背景工作者:

private void bw2_DoWork(object sender, DoWorkEventArgs args)
{
    BackgroundWorker worker = sender as BackgroundWorker;
    func.sshConnect();
    for (int num = 0; num < checklist.Items.Count; num++)
    {
        if (checklist.GetItemChecked(num))
        {
            string project = checklist.Items[num].ToString();
            lblStatus.Text = "Opening " + project + "..."; //error here
            if (func.svnCheckoutProject(project))
            {
                lblStatus.Text = project + " Opened"; //same error here
                func.sshRunCommand("echo " + project + " >> " + Properties.Settings.Default.serverUserFilesPath + Properties.Settings.Default.Username);
            }
            else
            {
                //error message
            }
        }
        worker.ReportProgress(num * (100 / checklist.Items.Count));
    }
}

我已经尝试用这个替换错误的行,但在visual studio中,它在调用时给它一个红线,并且不让我构建它。

lblStatus.Invoke((MethodInvoker)delegate { lblStatus.Text = "Opening " + project + "..."; });

Visual Studio在出现错误时将我指向此处:MSDN 我在复选框列表中使用了这种方法,但它可以用于标签并且它不起作用。

为什么它没有工作或以其他方式做这个的任何想法?

2 个答案:

答案 0 :(得分:9)

不要从DoWork事件更新UI控件 - 您在与UI线程不同的线程上。你可以调用Invoke,但它确实不适合它。

BackgroundWorker已经提供了一个构造,用于在工作正在运行时定期更新UI线程,并且您已经在使用它 - 它是ReportProgress方法。那是你应该更新你的标签的地方。其中的任何内容都会在主UI线程上运行。


您可以将所需的任何object传递给ReportProgess方法:

worker.ReportProgress(num * (100 / checklist.Items.Count),
                      string.Format("Opening {0} ...", project));

然后将值转换回来并在ProgressChanged事件中使用它:

void worker_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
    var message = e.UserState.ToString();

    lblStatus.Text = message;
}

答案 1 :(得分:2)

在大多数情况下,您可能希望使用BeginIvoke而不是Invoke

    public void changeLabelText(System.Windows.Forms.Label lib, String whateva)
    {
        if (lib.InvokeRequired)
        {
            lib.BeginInvoke(new MethodInvoker(() => changeLabelText(lib, whateva)));
        }
        else
        {
            lib.Text = whateva;
        }
    }

并在DoWork中调用方法

private void bw_DoWork(object sender, DoWorkEventArgs args)
{
//do something
//change the text of a label lb1
changeLabelText(lb1, "I'm reporting some progress....");
}