从工作线程更新表单控件的最佳方式是什么

本文关键字:最佳 方式 是什么 控件 表单 工作 线程 更新 | 更新日期: 2023-09-27 17:47:47

我做了一些研究,但我真的找不到从C#中的工作线程更新表单控件的首选方法。我知道BackgroundWorker组件,但在不使用BackgroundWorkers组件的情况下,最好的方法是什么?

从工作线程更新表单控件的最佳方式是什么

有一条一般的经验法则,即不要从UI线程本身以外的任何线程更新UI。使用BackgroundWorker的功能是个好主意,但如果您不想这样做,并且在另一个线程上发生了一些事情,则应该执行"Invoke"或BeginInvoke来强制委托在UI线程上执行该方法。

编辑:Jon B在评论中提出了这一点:

请记住Invoke()是synchronous和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."});

上面的代码来自这里的常见问题解答,以及这里更长、更复杂的代码。

为什么不想使用BackgroundWorker?它有一个名为ProgressChanged的奇妙回调事件,它可以让UI线程了解更新,非常适合progress栏类型的更新等。

链接到详细信息

这里有一个与此相关的讨论,这里也有一个。

从本质上讲,你可以使用Invoke来完成它

祝你好运!

在调用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);
        }