C# - 如果我使用 backgroundWorker,treeView 控件中不会显示任何内容

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

我喜欢在 "treeView1" 控件中填充数组 "numbers"。 如果我不使用 backgroundWorker 控件,一切都很好。

如果我使用 backgroundWorker,treeView1 中不会显示任何内容。看起来代码卡在了 foreach 循环中。

        //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;
    }

我尝试了您在下面建议的所有方法,但仍然没有显示任何内容

        //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();
    }

感谢 Banjamin 现在所有的工作:)

        //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; });
    }

如果您 运行 在调试器中编写代码,您将看到一个异常弹出窗口,为您提供有关错误原因的更多详细信息:

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.

您应该始终从应用程序的主线程(或 window)更新您的 UI。正确的代码是:

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; });
}

通过在 treeView1 和 button1 上使用 Invoke 方法,您可以确保使用正确的线程来更新 UI。