使用迭代器调用Listviewitems时System.argumentoutofrangeexception

时间:2014-12-27 04:49:52

标签: c# asynchronous iterator listviewitem

我有一个应用程序必须包含大量的项目并持续进入listviews控件:

    public Form1()
    {
        InitializeComponent();
    }

    private void button1_Click(object sender, EventArgs e)
    {
        deg_loadfile load = new deg_loadfile(loadfile);
        load.BeginInvoke(new AsyncCallback(loadcallback),null);
    }

    void countfile() {

        int listcount = listView1.Items.Count;          
        for (int x = 0; x < listcount; x++) {

            listView1.BeginInvoke((MethodInvoker)delegate {
                listView1.Items[x].SubItems[1].Text = "ok";
                listView1.Items[x].SubItems[2].Text = "ok";
                listView1.Items[x].SubItems[3].Text = "done";
            },x); 

        }

    }
    void countcallback(IAsyncResult ae) {
        MessageBox.Show("count finished");

    }
    delegate void deg_count();

    void loadcallback(IAsyncResult ae) {
        MessageBox.Show("finished");

    }
    delegate void deg_loadfile();
    void loadfile() {

        string file = File.ReadAllText("hughlist.txt");
        string[] files = Regex.Split(file,"\n");

        foreach (string str in files) {
            listView1.BeginInvoke((MethodInvoker)delegate {
                ListViewItem item = new ListViewItem(str);
                item.SubItems.Add("");
                item.SubItems.Add("");
                item.SubItems.Add("");
                listView1.Items.Add(item);                
            },str);          
        } 
    }

    private void button2_Click(object sender, EventArgs e)
    {
        deg_count count = new deg_count(countfile);
        count.BeginInvoke(new AsyncCallback(countcallback),null);

    }

上面的代码抛出system.argumentoutofrangeexception(请参见下图)

链接图片:http://i.stack.imgur.com/WJ7sA.png

迭代超出了我给出的条件,为什么会发生(注意:在我的情况下,我必须使用“for”而不是“foreach”或其他枚举)?

THX

更新 thx到@saruman的答案(关键字是“访问修改后的闭包”),我已经更新了以下代码

for (int x = 0; x < listcount; x++) {
            var x1=x;
            listView1.BeginInvoke((MethodInvoker)delegate
            {
                listView1.Items[x1].SubItems[1].Text = "ok";
                listView1.Items[x1].SubItems[2].Text = "ok";
                listView1.Items[x1].SubItems[3].Text = "done";
            }, x1); }

1 个答案:

答案 0 :(得分:1)

查找对修改后的闭包的访问

试试这个

var listcount = listView1.Items.Count;
for (var x = 0; x < listcount; x++)
{
   var x1 = x;
   listView1.BeginInvoke((MethodInvoker)delegate
   {
      listView1.Items[x1].SubItems[1].Text = "ok";
      listView1.Items[x1].SubItems[2].Text = "ok";
      listView1.Items[x1].SubItems[3].Text = "done";
   });
}