2011-10-05 83 views
0

我最近一直在处理一个应用程序,我想通过StatusBar控件中包含的ToolStripProgressBar控件在状态栏中显示另一个线程的进度。在我试图添加这段代码之前,我原本的代码改变了ToolStripStatusLabel控件的文本,为此我使用了委托的Invoke方法,并且一切正常。但是,我发现当我尝试使用ToolStripProgressBar时,状态栏的Invoke方法调用失败,没有通知(没有错误,没有例外,没有任何提示)。自从我学到了以后,我要用一个BackgroundWorker控件来使用进度条。所以我的代码工作,但我不明白为什么我不能使用已经似乎工作的Invoke方法。为什么StatusBar.Invoke方法不适用于ToolStripProgressBar?

的什么工作,什么都没有的一些例子:

这个工作

public delegate void changeStatusMessage(String message); 
public changeStatusMessage changeStatusMessageDelegate; 
public void changeStatusMessageMethod(String message){ 
     if(statusbar.InvokeRequired){ 
      statusbar.Invoke(changeStatusMessageDelegate, new Object[] {message}); 
     }else{ 
      toolstripLabel.Text = message; 
     } 
} 

这不起作用

public delegate void incrementProgressBar(int value); 
public incrementProgressBar incrementProgressBarDelegate; 
public void incrementProgressBarMethod(int value){ 
     if(statusbar.InvokeRequired){ 
      statusbar.Invoke(incrementProgressBarDelegate, new Object[] {value}); 
     }else{ 
      toolstripProgress.Increment(value); 
     } 
} 

在这个例子中,没有工作的InvokeRequired财产是真的,所以Invoke方法被调用,然后没有任何反应。正如我预计它再次调用incrementProgressBarMethod,这里InvokeRequired是错误的,因此允许Increment方法触发。

我真的很想知道为什么这不起作用。正如我所说我已经重新使用BackgroundWorker,我只想要一个解释。

+1

没有什么特殊的地方TSPB会交给你一个简单的解释。如果主线程被阻塞,Control.Invoke()往往容易死锁,所以“没有任何事情发生”并不罕见。坚持BackgroundWorker。 –

+0

我从来没有说过我想要一个“简单”的解释,复杂的解释也会起作用。简单地告诉我,Control.Invoke()可能导致死锁并不足以让我理解原因。 Control.Invoke()提供了一个原因,为什么我不能将它用于这一个控件,当用相同的代码以类似的方式处理控件时没有问题。 – JRSofty

+0

显示问题的任何人都可以测试,并且您会得到您的答案的过帐代码。 –

回答

0

调用postmessage API并在windows消息中排队消息。如果UI线程被阻塞,那么你可能会发生死锁,因为它不能推送排队的消息,什么都不会发生。所需调用的另一方不被解雇,如果有什么东西在等待它,砰,死锁。

这就是您需要小心Invoke的原因。

How to invoke a function on parent thread in .NET?

但你的问题是创建委托的,它是一个空的代表,你需要创建在同一个线程,它是由调用调用这个代表,因为其他的方式,下属系统会编组失败(它是一个指针)。

private void changeStatusMessageMethod(String message) 
    { 
     if (this.InvokeRequired) 
     { 
      var changeStatusMessageDelegate = new changeStatusMessage(changeStatusMessageMethod); 
      this.Invoke(changeStatusMessageDelegate, new Object[] { message }); 
     } 
     else 
     { 
      toolstripLabel.Text = message; 
     } 
    } 
    delegate void incrementProgressBar(int value); 
    private void incrementProgressBarMethod(int value) 
    { 
     if (this.InvokeRequired) 
     { 
      var incrementProgressBarDelegate = new incrementProgressBar(incrementProgressBarMethod); 
      this.Invoke(incrementProgressBarDelegate, new Object[] { value }); 
     } 
     else 
     { 
      toolstripProgress.Increment(value); 
     } 
    } 

这部作品的dotnet框架V4

private void button1_Click(object sender, EventArgs e) 
    { 
     var t = new System.Threading.Thread(new System.Threading.ThreadStart(x)); 
     t.Start(); 
    } 

    private void x() 
    { 
     do 
     { 
      changeStatusMessageMethod(DateTime.Now.ToString()); 
      System.Threading.Thread.Sleep(1000); 
     } while (true); 
    } 

    private void button2_Click(object sender, EventArgs e) 
    { 
     var t = new System.Threading.Thread(new System.Threading.ThreadStart(y)); 
     t.Start(); 
    } 

    private void y() 
    { 
     do 
     { 
      incrementProgressBarMethod(1); 
      System.Threading.Thread.Sleep(1000); 
     } while (true); 
    } 
相关问题