提供的行索引超出范围,即使在检查后也是如此

时间:2012-12-01 04:03:31

标签: c# winforms visual-studio-2010 visual-studio for-loop

我目前的代码:

Remove()
{
    for (int i = 0; i < ConGridView.RowCount; i++)
    {
        if (ConGridView.Rows[i].Cells[0].Value.ToString() == Address)
        {
            ConGridView.Rows.RemoveAt(i);
            break;
        }
    }
}

所以我每次客户端断开连接时都会调用remove函数。该函数将从datagridview中删除连接地址。当客户端逐个断开连接时,它可以很好地工作。但是,如果100个连接被丢弃并且它试图在不到一秒的时间内删除100个连接,那么它会错误地说“提供的行索引超出范围”。我应该如何检查?

到目前为止,我已尝试过: 试着抓。 if(ConGridView.Rows [i]!= null),if(i&lt; ConGridView.RowCount) 到目前为止似乎没有任何工作。我也得到了结果使用(i&lt; ConGridView.RowCount),其中我是26,而RowCount是24,但删除功能仍然激活..

对此有何想法?

6 个答案:

答案 0 :(得分:3)

你不能这样做。您的代码循环遍历ConGridView中的所有行,但它会像您一样删除它们。因此,在某些时候,您将尝试访问已删除的项目,这将导致您所描述的错误。

可能是以相反顺序迭代行的最佳方法。这样,删除末尾的行不会影响您在开始时访问行的时间。

答案 1 :(得分:1)

问题是您使用当前行数初始化for循环,然后从datagridview开始删除这些相同的行。在某些时候,你的for循环将尝试删除一个大于剩余行数的索引。

请改为尝试:

for (int i = ConGridView.RowCount - 1; i >= 0; i--)
{
    if (ConGridView.Rows[i].Cells[0].Value.ToString() == Address)
    {
        ConGridView.Rows.RemoveAt(i);
         break;
    }
}

答案 2 :(得分:1)

为什么不将总计数转换为单独的变量然后迭代

Remove()
{
    int totalConnections  = ConGridView.RowCount;

    for (int i = 0; i < totalConnections ; i++)
    {
        if (ConGridView.Rows[i].Cells[0].Value.ToString() == Address)
        {
            ConGridView.Rows.RemoveAt(i);
            break;
        }
    }
}

答案 3 :(得分:1)

此问题是因为您正在修改正在迭代的集合。如果使用临时数组和两个循环来删除条目会更好。

Remove()

// You can use an array/list or whatever you want below.
Collection<DataGridViewRow> rowsToDelete = new Collection<DataGridViewRow>();

        for (int i = 0; i < ConGridView.RowCount; i++)
        {
             if (ConGridView.Rows[i].Cells[0].Value.ToString() == Address)
                {
                        rowsToDelete.Add(ConGridView.Rows[i]);
                        break;
                }
        }

       // now remove the marked entries.
       foreach(DataGridViewRow deletedRow in rowsToDelete)
       {
           ConGridView.Rows.Remove(deletedRow);
       }

答案 4 :(得分:1)

从数组中删除项目时,会重建该项目;将剩余元素向上移动一个,以消除已删除的索引的间隙。

1. guybrush threepwood
2. murray
3. elaine
4. Jimmy Gibbs Jr.

如果你在这里删除2.项目;它变成了这个:

1. guybrush threepwood
2. elaine
3. Jimmy Gibbs Jr.

当你在迭代时,想象一下:

for (int i = 0; i < myArray.Count; i++)
{
    if (i == 2) myArray.RemoveAt(i);
}

在运行时,当i = 3时,3处的元素已经改变,你希望它是'elaine',但它是'Jimmy Gibbs Jr.'。解决此问题的一种方法是,如果我们删除它,请将i减少一个,确保i引用正确的值。

for (int i = 0; i < myArray.Count; i++)
{
    if (i == 2)
    {
         myArray.RemoveAt(i);
         i--;
    }
}

在这种情况下我会选择LINQ,但是这一切都更容易。

myArray.RemoveAll(x => x == "murray");

答案 5 :(得分:0)

我已经尝试了所有人在这里发布的所有建议,但错误仍然存​​在。

我用不同的方式解决了这个问题......我已经切换到TreeNodeView,因为那是我最终要使用的。现在我可以删除任意数量的连接:

For each(TreeNode TN in ConTreeView) 
{ 
   ConTreeView.Nodes.Remove(TN); 
}