[英]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.