从另一个线程更新标签

本文关键字:标签 更新 线程 另一个 | 更新日期: 2023-09-27 17:59:32

我在另一个类中使用一个线程来更新标签。标签是Winform Main类中的内容。

 Scanner scanner = new Scanner(ref lblCont);
 scanner.ListaFile = this.listFiles;
 Thread trd = new Thread(new ThreadStart(scanner.automaticScanner));
 trd.IsBackground = true;
 trd.Start();
 while (!trd.IsAlive) ;
 trd.Join();

您可以看到,我将标签的引用传递到第二个类的构造函数中。在第二类(扫描仪)中,我有一个名为"automaticScanner"的方法,它应该用以下代码更新标签:

public Scanner(ref ToolStripStatusLabel _lblContatore)
{
        lblCounter= _lblContatore;
}
Thread threadUpdateCounter = new Thread(new ThreadStart(this.UpdateCounter));
threadUpdateCounter.IsBackground = true;
threadUpdateCounter.Start();
while (!threadUpdateCounter .IsAlive) ;
threadUpdateCounter.Join();
private void AggiornaContatore()
{
  this.lblCounter.Text = this.index.ToString();        
}

我在标签更新时收到了这个错误:

跨线程操作无效:控件"Main"是从上创建的线程以外的线程访问的

我将.net 4与Winform C#一起使用。

非常感谢你的回答。

新闻:问题是这条线:

trd.Join();

这一行阻塞了我的GUI,标签没有更新。有什么方法可以控制线程的完成和更新标签直到结束?感谢

从另一个线程更新标签

您不能从UI线程以外的任何其他线程更新UI。使用此选项可以更新UI线程上的线程。

 private void AggiornaContatore()
 {         
     if(this.lblCounter.InvokeRequired)
     {
         this.lblCounter.BeginInvoke((MethodInvoker) delegate() {this.lblCounter.Text = this.index.ToString(); ;});    
     }
     else
     {
         this.lblCounter.Text = this.index.ToString(); ;
     }
 }

请阅读本书的这一章和更多内容,以清楚地了解线程:

http://www.albahari.com/threading/part2.aspx#_Rich_Client_Applications

使用MethodInvoker更新其他线程中的标签文本。

private void AggiornaContatore()
{
    MethodInvoker inv = delegate 
    {
      this.lblCounter.Text = this.index.ToString(); 
    }
 this.Invoke(inv);
}

您得到错误是因为您的UI线程持有标签,并且由于您试图通过另一个线程更新标签,您得到了跨线程异常。

您还可以看到:Windows窗体中的线程

只需使用Control.Invoke方法或Control.BeginInvoke方法。

很好的例子:如何:对Windows窗体控件进行线程安全调用。