I am using 5 BackgroundWorker objects running at the same time for a certain purpose, and all of them have to cha开发者_如何学运维nge the same label. How do I do that?
How do I modify the form from more than one thread then? And how do i do it in case i want to change a public string?
Use Control.Invoke with a delegate.
In your background worker thread, instead of saying
label4.Text = "Hello";
say
label4.Invoke(new Action(() =>
{
label4.Text = "Hello";
}
));
Everything inside the { } executes on the control's thread, so you avoid the exception.
This allows you to do arbitrary changes to your user interface from a BackgroundWorker
rather than just reporting progress.
You could use the ReportProgress method in your BackgroundWorker
where you want the label to change and write the actual code in ProgressChanged
event handler.
You should be very wary of calling the synchronous Invoke rather than the async BeginInvoke on a gui. You will soon have an unresponsive and sloppy gui that appears to be struggling to paint itself, as well as potential for deadlocks.
It depends on how often you update it - and does your background thread really need to wait for the gui to have returned? That sounds like a problem with your model.
As well as Control.BeginInvoke, you can have a look at SynchronizationContext.
When you're creating the BackgroundWorkers, assuming you're creating them from the UI thread, you pass in SynchronizationContext.Current to the workers. When the BackgroundWorkers are ready to invoke something back on the UI thread, they call the Synchronization.Post method on the SynchronizationContext instance passed in when they were created.
There are two good articles on SynchronizationContext here and here.
Take a look into this answer. It doesn't matter if you have one, five or thousand Worker threads (in meaning of concept).
精彩评论