如何使用后台工作程序将参数(字符串)发送到 UI 线程?

How can I send arguments(string) to the UI thread with the Background Worker?

我在应用程序上使用后台工作程序来更新 UI 上的进度条。我可以使用以下方式报告进度。

backgroundWorker.ReportProgress(barProgress);

问题是 ReportProgress 方法只接受一个整数作为参数,但我还需要传递一个字符串来更新进度条上的标签。

progressLabel.Text = "Passed Argument";        
progressLabel.Refresh();

我似乎找不到直接在 BackgroundWorker 对象上传递它的方法。有没有什么方法我没有看到或没有办法做到这一点?

可以,您只需调用与该控件关联的 Dispatcher

Dispatcher.BeginInvoke(new Action(()=>{
    progressLabel.Text = "Passed Argument";        
    progressLabel.Refresh();
});

UI 在单线程单元 (STA) 中运行,通常不允许跨线程访问(如果您之前尝试过此操作,您可能会遇到 CrossThreadException)。通过调用 Dispatcher,你基本上告诉它在轮到 UI 线程再次处理时执行什么。

只要确保您不从 UI-Thread 本身调用 Dispatcher.Invoke,那会使它死锁。如果您有可以从您的 UI 或另一个线程调用的方法,您可以检查您当前是否可以使用名为 CheckAccess 的隐藏方法(无自动完成或 IntelliSense)访问,该方法将 return true 如果您可以直接访问该控件,或者 false 如果您必须使用 Dispatcher。

The problem is that the ReportProgress method only takes an integer as parameter

其实还有一个ReportProgress方法overload that allows you to pass additional arbitrary object which then is accessible via ProgressChangedEventArgs.UserState属性.

例如:

backgroundWorker.ReportProgress(barProgress, "Passed Argument");

然后在 ProgressChanged 事件中:

progressLabel.Text = e.UserState as string;        
progressLabel.Refresh();

有一个 overload of ReportProgress 有一个 userstate 参数。这是 object 类型的,所以它可以是任何你喜欢的类型。

所以从您的 DoWork 处理程序调用它,如下所示:

backgroundWorker.ReportProgress(barProgress, "Passed Argument");

然后在您的 ProgressChanged 处理程序中访问它,如下所示:

progressLabel.Text = (string)e.UserState;        
progressLabel.Refresh();