2008-10-15 37 views

回答

10

有一个一般的经验法则,说不要从UI线程本身以外的任何线程更新UI。使用BackgroundWorker的功能是一个好主意,但您不希望在不同的线程上发生某些事情,您应该执行“Invoke”或BeginInvoke来强制委托在UI线程上执行该方法。

编辑:乔恩乙方在意见中提出这点好:

记住调用()是 同步而BeginInvoke()是 异步的。如果使用Invoke(),那么 必须小心,不要导致 死锁。我会推荐 BeginInvoke(),除非你真的需要 这个调用是同步的。

一些简单的示例代码:

// Updates the textbox text. 
private void UpdateText(string text) 
{ 
    // Set the textbox text. 
    m_TextBox.Text = text; 
} 

public delegate void UpdateTextCallback(string text); 

// Then from your thread you can call this... 
m_TextBox.Invoke(new UpdateTextCallback(this.UpdateText), 
    new object[]{"Text generated on non-UI thread."}); 

上面的代码是从一个关于它here和更长的更复杂的一个here FAQ。

+0

m_TextBox.Invoke究竟做了什么?它是否强制委托在UI线程上执行?确切地说, – Yttrium 2008-10-15 23:48:00

5

为什么不使用BackgroundWorker来做它?它有一个梦幻般的回调事件,名为ProgressChanged,它让UI线程知道更新,完美适用于Progess条形更新等。

link to details

1

有与此相关的here和一个here的讨论。

本质上,您使用Invoke来完成它。

祝你好运!

1

我还会在调用Invoke时考虑InvokeRequired(仅限于VS2008)。有时您不会从单独的线程更新UI。它节省了创建委托等的开销。

if (InvokeRequired) 
     { 
      //This.Invoke added to circumvent cross threading exceptions. 
      this.Invoke(new UpdateProgressBarHandler(UpdateProgressBar), new object[] { progressPercentage }); 
     } 
     else 
     { 
      UpdateProgressBar(progressPercentage); 
     } 
相关问题