我已经做了一些研究,但我真的找不到从 C# 中的工作线程更新表单控件的首选方法。我知道 BackgroundWorker 组件,但是不使用 BackgroundWorker 组件的最佳方法是什么?
Yttrium
问问题
15470 次
4 回答
10
有一条一般的经验法则是说不要从 UI 线程本身以外的任何线程更新 UI。使用 BackgroundWorker 的功能是个好主意,但您不想这样做,并且在不同的线程上发生了一些事情,您应该执行“Invoke”或 BeginInvoke 以强制委托在 UI 线程上执行该方法。
编辑:Jon B 在评论中提出了这一点:
请记住,Invoke() 是同步的,而 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."});
于 2008-10-15T23:24:09.300 回答
5
你为什么不想使用 BackgroundWorker 来做呢?它有一个很棒的回调事件,叫做 ProgressChanged,它让 UI 线程知道更新,非常适合进度条类型的更新等。
于 2008-10-15T23:16:11.470 回答
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);
}
于 2008-10-16T00:16:14.970 回答