循环后台worker

时间:2015-09-21 17:05:43

标签: c# listview for-loop backgroundworker

我正在尝试更改后台工作程序中的列表视图。

 private void bw2_DoWork(object sender, DoWorkEventArgs e)
    {
        String temp = "aaaa";
        int n;
        int nNet;
        String[] ar = (String[])e.Argument;
        int nList = int.Parse(ar[3]);

        String tTrain = ar[0];
        String tPredic = ar[1];
        this.BeginInvoke(new MethodInvoker(() => { nList = inputList.Items.Count; }));
        for (int i = 0; i < nList; i++)
        {
            Console.WriteLine(i);
            ListViewItem.ListViewSubItem temp1 = new ListViewItem.ListViewSubItem();
            temp1.BackColor = Color.Green;
            temp1.Text = "NORMAL";
             this.BeginInvoke( new MethodInvoker( () => { temp = String.Format("{0}\\{1}", dtrainTextBox.Text , inputList.Items[i].SubItems[1].Text); }));
          //  temp = String.Format("{0}\\{1}", tTrain, inputList.Items[i].SubItems[1].Text);
            if (!File.Exists(temp))
            {
                this.BeginInvoke(new MethodInvoker(delegate { inputList.Items[i].SubItems[1].BackColor = Color.Red; }));
              //  inputList.Items[i].SubItems[1].BackColor = Color.Red;
                temp1.BackColor = Color.Red;
                temp1.Text = "ERRO";
            }
            this.BeginInvoke(new MethodInvoker(() => { temp = String.Format("{0}\\{1}", dpredicTextBox.Text, inputList.Items[i].SubItems[1].Text); }));
           // temp = String.Format("{0}\\{1}", tPredic, inputList.Items[i].SubItems[2].Text);
            if (!File.Exists(temp))
            {
                this.BeginInvoke(new MethodInvoker(delegate { inputList.Items[i].SubItems[2].BackColor = Color.Red; }));
               // inputList.Items[i].SubItems[2].BackColor = Color.Red;
                temp1.BackColor = Color.Red;
                temp1.Text = "ERRO";
            }
            Console.WriteLine(String.Format("i:{0} nList:{1}",i,nList));
            this.BeginInvoke(new MethodInvoker(() => { temp = inputList.Items[i].SubItems[0].Text; }));
            //temp = inputList.Items[i].SubItems[0].Text
            Console.WriteLine(temp);
            if (int.TryParse(temp, out n) & int.TryParse(ar[2], out nNet))
            {
                if (n > nNet)
                {
                    this.BeginInvoke(new MethodInvoker(delegate { inputList.Items[i].SubItems[0].BackColor = Color.Red; }));
                 //   inputList.Items[i].SubItems[0].BackColor = Color.Red;
                    temp1.BackColor = Color.Red;
                    temp1.Text = "ERRO";
                }
            }
            else
            {
                this.BeginInvoke(new MethodInvoker(delegate { inputList.Items[i].SubItems[0].BackColor = Color.Red; }));
               // inputList.Items[i].SubItems[0].BackColor = Color.Red;
                temp1.BackColor = Color.Red;
                temp1.Text = "ERRO";
            }

            this.BeginInvoke(new MethodInvoker(delegate{inputList.Items[i].SubItems.Add(temp1);}));
        }
    }

问题在于nList我正在测试nList = 2060并且我在其中一个inputList.Items[i]中收到错误:

  

类型'System.ArgumentOutOfRangeException'的未处理异常   发生在System.Windows.Forms.dll其他信息:   InvalidArgument ='2060'的值对'index'无效。

我不知道这是怎么回事,“i”的最后一个值应该是2059,它是如何尝试访问这个索引2060的。 nList有inputList.Items.Count值,我把它作为参数传递给我,因此我不需要使用invoke来获取它的数量。

我刚试过这个:

 private void loadButton_Click(object sender, EventArgs e)
    {
        object[] ar = { dpredicTextBox.Text, dpredicTextBox.Text, nNet.Items.Count,  inputList};
        bw3.RunWorkerAsync(ar);
    }
private void bw3_DoWork(object sender, DoWorkEventArgs e)
    {
        String temp = "aaaa";
        int n;
        object[] ar = (Object[])e.Argument;
        ListView nList = (ListView) ar[3];
        int nNet = (int)ar[2];
        String tTrain = (String) ar[0];
        String tPredic = (String) ar[1];
        foreach(ListViewItem item in nList.Items)
        {
            ListViewItem.ListViewSubItem temp1 = new ListViewItem.ListViewSubItem();
            temp1.BackColor = Color.Green;
            temp1.Text = "NORMAL";
            temp = String.Format("{0}\\{1}", tTrain, item.SubItems[1].Text); 
            if (!File.Exists(temp))
            {

                item.SubItems[1].BackColor = Color.Red;
                temp1.BackColor = Color.Red;
                temp1.Text = "ERRO";
            }
            temp = String.Format("{0}\\{1}", tPredic, item.SubItems[2].Text);
            if (!File.Exists(temp))
            {
                item.SubItems[2].BackColor = Color.Red;
                temp1.BackColor = Color.Red;
                temp1.Text = "ERRO";
            }
            temp = item.SubItems[0].Text;
            if (int.TryParse(temp, out n))
            {
                if (n > nNet)
                {
                    item.SubItems[0].BackColor = Color.Red;
                    temp1.BackColor = Color.Red;
                    temp1.Text = "ERRO";
                }
            }
            else
            {
                item.SubItems[0].BackColor = Color.Red;
                temp1.BackColor = Color.Red;
                temp1.Text = "ERRO";
            }
            item.SubItems.Add(temp1);
            this.BeginInvoke(new MethodInvoker(delegate { inputList = nList; }));
        }
       // this.BeginInvoke(new MethodInvoker(delegate { inputList = nList; }));
    }

但它也不起作用:

System.Windows.Forms.dll中发生了'System.InvalidOperationException'类型的异常,但未在用户代码中处理

附加信息:跨线程操作无效:控制'inputList'从其创建的线程以外的线程访问。

1 个答案:

答案 0 :(得分:0)

使用BeginInvoke而不是异步的Invoke。实际上,计数器i在循环结束时变为2060,这可能发生在inputList.Items[i]在一个异步调用中被引用之前。在WinForms控件上调用Invoke方法会等待调用完成并使循环按预期运行。您的第二个代码示例不起作用,因为无法从后台线程“触摸”WinForms控件。它们只能从主(或GUI)线程访问。