Search code examples
c#backgroundworkerinvokerequired

Updating array of labels from backgroundworkers


I am trying to update an array of Labels which are on a form from a backgroundworker. Here is my code:

for (int i = 0; i < 6; i++)
{
    if (this.InvokeRequired)
    {
        this.Invoke((MethodInvoker)delegate
        {
            arrLabel[i].Text = values[i].ToString();
        });
    }
    else
    {
        arrLabel[i].Text = values[i].ToString();
    }
}

This does not work, but if I try to change text property of each label instead of the array, it works. How can I fix this? Also is there a shorter/better way of updating form controls from backgroundworkers than what I am doing for every single control on my form?

Edit: here is how I defined the array:

  private Label[] arrLabel = new Label[6];

and here is the function that I call to assign the array:

    private void makeLabelArrays()
    {
        for (int i = 0; i < 6; i++)
        {
            arrLabel[i] = (Label)Groupbox1.Controls["label" + (i + 1).ToString()];
        }
    }

Solution

  • I'm assuming what some of your code looks like; I may be wrong.

    You can use the ReportProgress() method to send two pieces of information back to the UI thread - the percentage of completeness (doesn't really apply in your case so I specified 0) and some piece of data (any object you want, just a number in this case).

    Then you can get the data in the ProgressChanged event and execute code that touches the UI.

    private List<Label> arrLabel = new List<Label>();
    private List<string> values = new List<string>(); 
    
    private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
    {
        var bw = (BackgroundWorker)sender;
    
        for (int i = 0; i < 6; i++)
            bw.ReportProgress(0, i);
    }
    
    private void backgroundWorker1_ProgressChanged(object sender, ProgressChangedEventArgs e)
    {
        var currentIndex = Convert.ToInt32(e.UserState);
    
        arrLabel[currentIndex].Text = values[0].ToString();
    }
    

    Make sure you enable reporting progress, as it's disabled by default.

    backgroundWorker1.WorkerReportsProgress = true;