如何从 BackgroundWorker 线程中更新标签?

How do I update a Label from within a BackgroundWorker thread?

当我使用 WinForms 时,我会在我的 bg_DoWork 方法中这样做:

status.Invoke(new Action(() => { status.Content = e.ToString(); }));
status.Invoke(new Action(() => { status.Refresh(); }));

但是在我的 WPF 应用程序中,我收到一条错误消息,指出 Invoke 对于 Label 不存在。

如有任何帮助,我们将不胜感激。

您需要使用

Dispatcher.Invoke(new Action(() => { status.Content = e.ToString(); }))

而不是status.Invoke(...)

使用 BackgroundWorker 中已经内置的功能。当您 "report progress" 时,它会将您的数据发送到 ProgressChanged 事件,该事件在 UI 线程上运行。无需调用 Invoke().

private void bgWorker_DoWork(object sender, DoWorkEventArgs e)
{
    bgWorker.ReportProgress(0, "Some message to display.");
}

private void bgWorker_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
    status.Content = e.UserState.ToString();
}

确保设置 bgWorker.WorkerReportsProgress = true 以启用报告进度。

这对你有帮助。

要同步执行:

Application.Current.Dispatcher.Invoke(new Action(() => { status.Content = e.ToString(); }))

异步执行:

Application.Current.Dispatcher.BeginInvoke(new Action(() => { status.Content = e.ToString(); }))

如果您使用的是 WPF,我建议您研究一下 DataBinding。

解决此问题的 "WPF way" 是将标签的 Content 属性 绑定到模型的某些 属性。这样,更新模型会自动更新标签,您不必担心自己编组线程。

有很多关于 WPF 和数据绑定的文章,这可能是一个很好的起点:http://www.wpf-tutorial.com/data-binding/hello-bound-world/

您真的应该考虑在 WPF 中使用 "Data Binding" 的强大功能。

您应该更新视图模型中的一个对象并将其绑定到您的用户界面控件。

参见 MVVM Light。简单易用。没有它就不要编写 WPF。