简体   繁体   English

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

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

I am using a Background worker on an application to update a progress bar on the UI. 我在应用程序上使用后台工作程序更新UI上的进度条。 I am able to report the progress using the following. 我可以使用以下方法报告进度。

backgroundWorker.ReportProgress(barProgress);

The problem is that the ReportProgress method only takes an integer as parameter, but I also need to pass a string to update a label on the progress bar. 问题在于ReportProgress方法仅采用整数作为参数,但是我还需要传递一个字符串来更新进度条上的标签。

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

I can't seem to find a method to pass it directly on the BackgroundWorker object. 我似乎找不到找到直接将其传递给BackgroundWorker对象的方法。 Is there any method I'm not seeing or a way to do this? 有没有我看不见的方法或执行此操作的方法?

The problem is that the ReportProgress method only takes an integer as parameter 问题在于ReportProgress方法仅采用整数作为参数

Actually there is another ReportProgress method overload that allows you to pass additional arbitrary object which then is accessible via ProgressChangedEventArgs.UserState property. 实际上,还有另一个ReportProgress方法重载 ,它允许您传递其他任意对象,然后可以通过ProgressChangedEventArgs.UserState属性对其进行访问。

For instance: 例如:

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

and then inside the ProgressChanged event: 然后在ProgressChanged事件中:

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

There is an overload of ReportProgress that has a userstate parameter. ReportProgress重载具有一个userstate参数。 This of type object , so it can be anything you like. 此类型为object ,因此可以是任何您喜欢的类型。

So call it from your DoWork handler like so: 因此,请从您的DoWork处理程序中调用它,如下所示:

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

And access it in your ProgressChanged handler like so: 并按如下方式在您的ProgressChanged处理程序中访问它:

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

Yes you can, you just need to call the Dispatcher associated with that control. 是的,可以,您只需要调用与该控件关联的Dispatcher

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

The UI runs in a Single Thread Apartment (STA) and usually doesn't allow Cross Thread Access (You might have gotten a CrossThreadException if you tried this before). UI在单线程单元(STA)中运行 ,通常不允许跨线程访问 (如果之前尝试过,可能会遇到CrossThreadException )。 By calling the Dispatcher you basically tell it what to execute when it's the UI-thread's turn to process again. 通过调用Dispatcher您基本上告诉它在再次执行UI线程时要执行的操作。

Just make sure you don't call Dispatcher.Invoke from the UI-Thread itself, that would deadlock it. 只要确保您不从UI-Thread本身调用Dispatcher.Invoke ,就会死锁它。 If you have methods that can be called from either your UI or another thread, you can check if you currently have access with a hidden method (no autocomplete or IntelliSense) called CheckAccess that will return true if you can access that control directly or false if you have to use the Dispatcher. 如果您有可以从用户界面或其他线程调用的方法,则可以检查是否当前使用名为CheckAccess的隐藏方法(无自动完成或IntelliSense)进行访问,如果您可以直接访问该控件,则该方法将返回true否则,则返回false您必须使用Dispatcher。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM