使用 C# 交叉线程设置标签的值

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/2172467/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-07 00:07:13  来源:igfitidea点击:

Set value of label with C# Cross Threading

c#multithreading

提问by Lawrence

I need help with setting/changing the value of a label in my C# program whenever I try it an error occurs saying I need to cross thread it all. Can anyone write some code to help me with that? My code is:

每当我尝试在 C# 程序中设置/更改标签值时,我都需要帮助,出现错误提示我需要将其全部交叉线程。任何人都可以写一些代码来帮助我吗?我的代码是:

int number = 0;
int repeats = Convert.ToInt32(textBox2.Text);

while (number < repeats)
{
   repeats++;
   label5.Text = "Requested" + repeats + "Times";
}

Can anyone help me? Thanks.

谁能帮我?谢谢。

采纳答案by JaredPar

Try the following to update the value

尝试以下操作来更新值

label5.Invoke((MethodInvoker)(() => label5.Text = "Requested" + repeats + "Times"));

The Invoke method (from Control.Invoke) will cause the passed in delegate to be run on the thread which the given Controlis affinitized to. In this case it will cause it to run on the GUI thread of your application and hence make the update safe.

Invoke 方法 (from Control.Invoke) 将导致传入的委托在给定Control关联的线程上运行。在这种情况下,它将导致它在应用程序的 GUI 线程上运行,从而使更新安全。

回答by Michael

You can add this extension method that I regularly use (similar in technique to @JaredPar's answer):

您可以添加我经常使用的这个扩展方法(在技术上类似于@JaredPar 的回答):

  /// <summary>
  /// Extension method that allows for automatic anonymous method invocation.
  /// </summary>
  public static void Invoke(this Control c, MethodInvoker mi)
  {
     c.Invoke(mi);

     return;
  }

You can then use on any Control (or derivatives) natively in your code via:

然后,您可以通过以下方式在代码中本地使用任何控件(或衍生产品):

// "this" is any control (commonly the form itself in my apps)  
this.Invoke(() => label.Text = "Some Text");

You can also execute multiple methods via anonymous method passing:

您还可以通过匿名方法传递来执行多个方法:

this.Invoke
(
   () =>
   {
      // all processed in a single call to the UI thread
      label.Text = "Some Text";
      progressBar.Value = 5;
   }
);

Bear in mind that if your threads are trying to Invoke on a control that is disposed, you'll get an ObjectExposedException. This happens if a thread hasn't yet aborted by the application is shutting down. You can either "eat" the ObjectDisposedException by surrounding your Invoke() call, or you can "eat" the exception in the Invoke() method extension.

请记住,如果您的线程试图调用已释放的控件,您将收到 ObjectExposedException。如果应用程序关闭尚未中止线程,则会发生这种情况。您可以通过包围 Invoke() 调用来“吃掉”ObjectDisposedException,也可以“吃掉”Invoke() 方法扩展中的异常。