0

I found several examples that shows how to update UI control using BackgroundWorker.

For example the following code:

BackgroundWorker backgroundWorker1 = new BackgroundWorker();  
backgroundWorker1.WorkerReportsProgress = true;  

//start the operation on another thread  
private void btnStart_Click(object sender, EventArgs e)  
{  
    backgroundWorker1.RunWorkerAsync();  
}  

//DoWork event handler is executed on a separate thread  
private void backgroundWorker1_DoWork(object sender, DoWorkeventArgs e)  
{  
    //a long running operation  
    for (int i = 1; i < 11; i++)  
    {     
        Thread.Sleep(2000);  
        backgroundWorker1.ReportProgress(i * 10);  
    }  
}  

private void backgroundWorker1_ProgressChanged(object sender, ProgressChangedEventArgs e)  
{  
    progressBar1.value = e.ProgressPercentage;  
}  

That I found here:

https://www.c-sharpcorner.com/UploadFile/Ashush/using-the-backgroundworker-component

The problem is that ALL the examples that I found, shows how to update Only One control on the form. For example the code that I gave, demonstrate how to update a progressBar value.

But this is not a realistic situation, in the real world, I would usually want to update SEVERAL controls on my form.

For example:

progressBar1.Value = 54;

listBox1.SelectedIndex = 2;

button1.BackgroundColor = Color.Yellow;

image1.left = image1.left + 20;

How do I change the code that I showed, in order to update the controls that I gave in the previous lines? There must be an easy way to do that. By the way, my application uses several threads, and each one of them have to update several controls on the UI while they are still running...

I Hope that my question is clear, Thanks.

Edit:

Neil suggested me to find the solution in this thread:

How do I update the GUI from another thread?

But I saw that people there recommended using BackgroundWorker... which is exactly what I'm asking about.

They didn't explain how to use this method in order to update several UI controls in parallel.

Robert
  • 13
  • 5
  • You can't update a UI element from a background thread. You need to `Invoke` the update on the UI thread. `ReportProgress` is a special version of the invoke strategy. – Neil Aug 30 '22 at 16:55
  • Does this answer your question? [How do I update the GUI from another thread?](https://stackoverflow.com/questions/661561/how-do-i-update-the-gui-from-another-thread) – Neil Aug 30 '22 at 16:55
  • Change the Report Prgress to send stateobject. The state object can contain information like which GUI should be updated. See : https://learn.microsoft.com/en-us/dotnet/api/system.componentmodel.backgroundworker.reportprogress?view=net-6.0#system-componentmodel-backgroundworker-reportprogress(system-int32-system-object) – jdweng Aug 30 '22 at 16:58
  • @Neil : You are wrong. You need to use the Report Progress Event. – jdweng Aug 30 '22 at 16:59
  • @Neil Are you saying that BackgroundWorker() is good only for one control updating? It looks to me very limited... – Robert Aug 30 '22 at 17:03
  • @Neil I saw this thread before I posted my question, and I saw that people there recommended using BackgroundWorker... – Robert Aug 30 '22 at 17:06
  • Question to all: May I use a global perameter like: int controlToUpdate, that will tell the ProgressChanged() method which control does it need to update? For example: if (controlToUpdate == 1) textBox1.Text = "ABC"; else if (controlToUpdate == 2) button1.BackgroundColor = Color.Yellow; else if (controlToUpdate == 3) listBox1.Items.Add("New line"); Will it work? – Robert Aug 30 '22 at 17:18
  • For your info, there might be better ways to do work in the background with progress reporting, than the old and awkward `BackgroundWorker` class. Take a look [here](https://stackoverflow.com/questions/12414601/async-await-vs-backgroundworker/64620920#64620920 "Async/await vs BackgroundWorker") for an alternative (`Task.Run` + `await` + `IProgress`). – Theodor Zoulias Aug 30 '22 at 17:41

1 Answers1

0

Try something like this:

button1.Invoke(
    new Action(
        () =>
        button1.BackgroundColor = Color.Yellow;
        )
    );
image1.Invoke(
    new Action(
        () =>
        image1.left = image1.left + 20;
        )
    );
//etc.