3

我在我的 Winform 中使用后台工作线程,在我的 Do_Work 事件中我正在计算一些东西,我需要的是同时我想更新主/UI线程中的标签?如何做到这一点?

我想从 Do_Work 事件中更新我的标签...

4

5 回答 5

9

在 WinForms(以及 WPF)中,UI 控件只能在 UI 线程中更新。您应该以这种方式更新您的标签:

public void UpdateLabel(String text){
    if (label.InvokeRequired)
    {
        label.Invoke(new Action<string>(UpdateLabel), text);
        return;
    }      
    label.Text = text;
}
于 2012-06-26T16:52:14.520 回答
1

在您的Do_Work方法中,您可以使用对象的Invoke()方法在其 UI 线程上执行委托,例如:

this.Invoke(new Action<string>(UpdateLabel), newValue);

...然后确保将这样的方法添加到您的类中:

private void UpdateLabel(string value)
{
    this.lblMyLabel.Text = value;
}
于 2012-06-26T16:13:09.713 回答
0

您在用户界面(标签)更新期间面临跨线程异常的问题,因为它(UI)位于不同的线程(主线程)中。您可以使用许多选项,例如 TPL、ThreadPool、等等,但是做您想做的事情的简单方法想要在您的 Do_Work 方法中编写一个简单的 Action 作为

私人无效背景工人1_DoWork(对象发送者,DoWorkEventArgs e)

{
    x++;
    //you can put any value
    Action = act =()=>
           {
              label.Text = Convert.ToString(x);
           };
     if (label.InvokeRequired)
         label.BeginInvoke(act);
     else
          label.Invoke(act);
    backgroundWorker1.ReportProgress(0);
}
于 2012-07-14T21:34:52.047 回答
0

我希望这有帮助:

  int x = 0;
    private void backgroundWorker1_ProgressChanged(object sender, ProgressChangedEventArgs e)
    {

        label1.Text = x.ToString();
    }

    private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
    {
        x++;
        //you can put any value
        backgroundWorker1.ReportProgress(0);
    }

    private void button6_Click(object sender, EventArgs e)
    {
        backgroundWorker1.RunWorkerAsync();
    }
于 2012-06-26T16:47:52.637 回答
0

使用扩展方法的更通用的解决方案。这允许您更新任何控件的 Text 属性。

public static class ControlExtensions
{
   public static void UpdateControlText(this Control control, string text)
   {
      if (control.InvokeRequired)
      {
         _ = control.Invoke(new Action<Control, string>(UpdateControlText), control, text);
      }

      control.Text = text;
   }

   public static void UpdateAsync(this Control control, Action<Control> action)
   {
      if(control.InvokeRequired)
      {
         _ = control.Invoke(new Action<Control, Action<Control>>(UpdateAsync), control, action);
      }

      action(control);
   }
}

你可以使用这样的方法:

TextBox1.UpdateControlText(string.Empty); // Just update the Text property

// Provide an action/callback to do whatever you want.
Label1.UpdateAsync(c => c.Text = string.Empty); 
Button1.UpdateAsync(c => c.Text == "Login" ? c.Text = "Logout" : c.Text = "Login");
Button1.UpdateAsync(c => c.Enabled == false);
于 2021-02-04T09:42:32.883 回答