简体   繁体   中英

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. 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.

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

I can't seem to find a method to pass it directly on the BackgroundWorker object. 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

Actually there is another ReportProgress method overload that allows you to pass additional arbitrary object which then is accessible via ProgressChangedEventArgs.UserState property.

For instance:

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

and then inside the ProgressChanged event:

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

There is an overload of ReportProgress that has a userstate parameter. This of type object , so it can be anything you like.

So call it from your DoWork handler like so:

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

And access it in your ProgressChanged handler like so:

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

Yes you can, you just need to call the Dispatcher associated with that control.

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). By calling the Dispatcher you basically tell it what to execute when it's the UI-thread's turn to process again.

Just make sure you don't call Dispatcher.Invoke from the UI-Thread itself, that would deadlock it. 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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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