2017-05-09 40 views
1

出于某种原因,ToolStrip的ProgressBar和标签不会从其他线程更新。大量阅读后,我想出了这个,但仍然不工作(但按钮是好的,但不是在状态栏上)。C#Toolstrip的进度条和标签未从跨线程操作更新

public void GdmReaderMessageEvent(object sender, GdmMessagesEventArgs e) 
    { 
     Console.WriteLine(e.Message); 

     // error or abort 
     if (e.Message.StartsWith("Error:") || e.Message.StartsWith("Aborted")) 
     { 

      // cross thread crap 
      if (pb.GetCurrentParent().InvokeRequired) 
       pb.GetCurrentParent().Invoke(new MethodInvoker(delegate { pb.Visible = false; })); 

      if (lblStatus.GetCurrentParent().InvokeRequired) 
       lblStatus.GetCurrentParent().Invoke(new MethodInvoker(delegate { lblStatus.Text = e.Message; })); 

      btnImport.Invoke(new MethodInvoker(delegate { btnImport.Text = "Import"; })); 

      //lblStatus.Text = e.Message; 
      //btnImport.Text = "Import"; 
      //pb.Visible = false; 
     } 
    } 

编辑,现在所有功能,但这只是一个BGW线程回调,我认为它已经很明显。如果我只用它:

 lblStatus.Text = e.Message; // this is a Label inside Status 
     btnImport.Text = "Import"; // this is just a button on Form 
     pb.Visible = false;   // this is a Progress Bar inside Status  

会发生交叉线程错误。所以这就是为什么我使用Invoke()。 现在按钮可以更新,但状态栏中的所有控件都不是。

希望现在更清楚。

我使用.NET 3.5,VS2008,Winforms。 任何解决方案?

+0

你的平台是什么?的WinForms? WPF?的WebForms?请贴上标签 –

+2

是否符合条件?我知道这是一个奇怪的问题,但我没有看到整个函数,所以也许你已经在调用,或者无论出于什么原因都不需要它......你说按钮总是在工作 - 按钮没有被InvokeRequired选中。 ..被打破的2。 – Aaron

+1

亚伦可能已经回答了你的问题。我只想补充一点,你不必分别调用每个控件。调用可以确保包含的代码在与控件相同的线程上执行。你通过名字引用你的控件,所以你很可能在你的表单中,一个表单也是一个控件,因此你可以将它简化成一个'this.Invoke(...)',并把所有GUI更新代码放在那里。 – Fixation

回答

0

好吧,我找到了。 @Fixation,谢谢你带着“这个”(我的意思是表格本身)指导我。我试图使用不起作用的控件的调用。

而且,这个职位是非常有用 unable to update progress bar with threading in C#

 this.BeginInvoke((Action)(() => pb.Visible = false)); 
     this.BeginInvoke((Action)(() => lblStatus.Text = e.Message)); 

恰到好处,谢谢。