web-dev-qa-db-fra.com

Mettre à jour l'étiquette à partir d'un autre fil

J'utilise un thread écrit dans une autre classe pour mettre à jour une étiquette. L'étiquette est contenue dans la classe principale de Winform.

 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();

Comme vous pouvez le voir, je passe la référence de label au constructeur de la deuxième classe. Dans la deuxième classe (Scanner), j'ai une méthode appelée "automaticScanner" qui devrait mettre à jour l'étiquette avec ce code:

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();        
}

J'ai reçu cette erreur lors de la mise à jour de l'étiquette:

Opération entre les threads non valide: contrôlez "principal" accessible à partir d'un thread autre que le thread sur lequel il a été créé

J'utilise .net 4 avec Winform C #.

Merci beaucoup pour les réponses.

News: Le problème est cette ligne:

trd.Join();

Cette ligne bloque mon interface graphique et l'étiquette n'a pas été mise à jour. Il existe des méthodes pour contrôler la fin du fil et mettre à jour l'étiquette jusqu'à la fin? Merci

19
Antonio

Vous ne pouvez pas mettre à jour l'interface utilisateur à partir d'un autre thread que le thread d'interface utilisateur. Utilisez-le pour mettre à jour le thread sur le thread de l'interface utilisateur.

 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(); ;
     }
 }

Veuillez parcourir ce chapitre et d'autres extraits de ce livre pour obtenir une image claire du filetage:

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

47
Igoy

Utilisez MethodInvoker pour mettre à jour le texte de l'étiquette dans un autre fil.

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

 this.Invoke(inv);
}

Vous obtenez l'erreur parce que votre thread d'interface utilisateur contient l'étiquette, et puisque vous essayez de le mettre à jour via un autre thread, vous obtenez une exception de thread croisé.

Vous pouvez également voir: Threading dans Windows Forms

11
Habib
3
Sergey Brunov