C# - If I use backgroundWorker nothing is displayed in the treeView control

319 Views Asked by At

I like to populate array "numbers" in a "treeView1" control. All works well if I don't use backgroundWorker control.

If I use backgroundWorker nothing is displayed in the treeView1. It looks like the code is stuck in the foreach loop.

enter image description here

        //Step1
    private void button1_Click(object sender, EventArgs e)
    {          
        CheckForIllegalCrossThreadCalls = false;
        backgroundWorker1.RunWorkerAsync();
        button1.Enabled = false;
    }

    //Step2
    private void backgroundWorker1_DoWork_1(object sender, DoWorkEventArgs e)
    {
        int[] numbers = new int[5];
        numbers[0] = 1;
        numbers[1] = 2;
        numbers[2] = 3;
        numbers[3] = 4;
        numbers[4] = 5;

        foreach (int element in numbers)
        {
            treeView1.Nodes.Add(element.ToString());
        }
        button1.Enabled = true;
    }

I tried all you suggested below and still doesn't display anything

        //Step1
    private void button1_Click(object sender, EventArgs e)
    {

        CheckForIllegalCrossThreadCalls = true;
        backgroundWorker1.WorkerReportsProgress = true;
        backgroundWorker1.WorkerSupportsCancellation = true;
        backgroundWorker1.RunWorkerAsync();
        button1.Enabled = false;
    }

    //Step2
    private void backgroundWorker1_DoWork_1(object sender, DoWorkEventArgs e)
    {
        this.treeView1.Nodes.Clear();

        int[] numbers = new int[5];
        numbers[0] = 1;
        numbers[1] = 2;
        numbers[2] = 3;
        numbers[3] = 4;
        numbers[4] = 5;
        treeView1.BeginUpdate();
        foreach (int element in numbers)
        {
            treeView1.Nodes.Add(element.ToString());
        }
        treeView1.EndUpdate();
        button1.Enabled = true;
        treeView1.Refresh();
    }

Thanks to Banjamin now all work :)

        //Step1
    private void button1_Click(object sender, EventArgs e)
    {

        CheckForIllegalCrossThreadCalls = false;
        backgroundWorker1.WorkerReportsProgress = true;
        backgroundWorker1.WorkerSupportsCancellation = true;
        backgroundWorker1.RunWorkerAsync();
        button1.Enabled = false;
    }

    //Step2
    private void backgroundWorker1_DoWork_1(object sender, DoWorkEventArgs e)
    {
        this.treeView1.Nodes.Clear();

        int[] numbers = new int[5];
        numbers[0] = 1;
        numbers[1] = 2;
        numbers[2] = 3;
        numbers[3] = 4;
        numbers[4] = 5;

        treeView1.Invoke((Action)delegate
        {
            foreach (int element in numbers)
            {
                treeView1.Nodes.Add(element.ToString());
            }
        });

        treeView1.EndUpdate();
        //button1.Enabled = true;
        treeView1.Refresh();
        System.Windows.Forms.MessageBox.Show("Completed");
        button1.Invoke((Action)delegate { button1.Enabled = true; });
    }
1

There are 1 best solutions below

4
On BEST ANSWER

If you run your code in the debugger you will get an exception popup giving you more details on what is going wrong:

Additional information: Action being performed on this control is being called from the wrong thread. Marshal to the correct thread using Control.Invoke or Control.BeginInvoke to perform this action.

You should always update your UI from the main (or window) thread of your application. The correct code is:

private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
{
    int[] numbers = new int[5];
    numbers[0] = 1;
    numbers[1] = 2;
    numbers[2] = 3;
    numbers[3] = 4;
    numbers[4] = 5;

    treeView1.Invoke((Action)delegate 
    {
       foreach (int element in numbers)
       {
           treeView1.Nodes.Add(element.ToString());
       }
   });

   button1.Invoke((Action) delegate { button1.Enabled = true; });
}

By using the Invoke method on treeView1 and button1 you ensure the correct thread is used to update the UI.