web-dev-qa-db-ja.com

別のスレッドからラベルを更新

ラベルを更新するために別のクラスで記述しているスレッドを使用します。ラベルは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();

表示方法は、ラベルの参照を2番目のクラスのコンストラクターに渡します。 2番目のクラス(スキャナー)には、「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();        
}

ラベルの更新時にこのエラーを受け取りました:

クロススレッド操作が無効です:作成されたスレッド以外のスレッドからアクセスされる「メイン」を制御します

Winform C#で.net 4を使用します。

答えてくれてありがとう。

ニュース:問題は次の行です。

trd.Join();

この行はGUIをブロックし、ラベルは更新されませんでした。スレッドの終了を制御し、最後までラベルを更新する方法はありますか?ありがとう

19
Antonio

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

47
Igoy

MethodInvoker を使用して、他のスレッドのラベルテキストを更新します。

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

 this.Invoke(inv);
}

UIスレッドがラベルを保持しているためにエラーが発生し、別のスレッドを介してラベルを更新しようとしているため、クロススレッド例外が発生しています。

次も表示される場合があります。 Windowsフォームでのスレッド化

11
Habib
3
Sergey Brunov