【问题标题】:Row Index provided is out of range, even after check提供的行索引超出范围,即使在检查后也是如此
【发布时间】:2012-11-19 07:47:27
【问题描述】:

我当前的代码:

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

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

到目前为止,我已经尝试过: 试着抓。 if (ConGridView.Rows[i] != null), if (i

对此有任何想法吗?

【问题讨论】:

  • 我已经用不同的方式解决了这个问题......我已经切换到 TreeNodeView,因为这就是我最终要使用的。现在我可以删除任意数量的连接: For each(ConTreeView 中的 TreeNode TN) { ConTreeView.Nodes.Remove(TN);我应该将此标记为答案吗?尽管它并没有真正按照预期的方式解决问题,而是采取了不同的方法。

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


【解决方案1】:

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

可能是它以相反顺序遍历行的最佳方法。这样,在末尾删除一行不会影响您何时访问开头的行。

【讨论】:

  • 您的意思是 teppic 的建议吗? for (int i = ConGridView.RowCount - 1; i >= 0; i--) 这似乎也不起作用。
  • 是否有类似“仅当存在时才尝试删除”
  • 是的,反向迭代工作。我已经做过很多次了。如果它对您不起作用,也许您应该更具体地了解“似乎不起作用”的含义。
  • 那么,如果它存在,你将如何测试?如果您访问它并且它不存在,那就是那里的错误。您可以每次通过循环测试 count 属性,但我认为这越来越愚蠢。通过反向迭代循环,我已经处理了很多次。问题解决了。
  • 我的代码正确的正是 teppic 所建议的。如果这有什么不同,我忘了提到它是在一个线程中运行的。当我尝试在 1 秒内删除 100 个连接时,我仍然收到“行索引超出范围错误”,其中 i 的值与总行数的值相同,但 remove at 方法仍在激活中。除非 i 低于 rowcount 值,否则它不应该激活,对吗?
【解决方案2】:

问题是您使用当前行数初始化 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;
    }
}

【讨论】:

  • 它不起作用。但是根据您的建议,我已经意识到一些事情并尝试了这个:for (int i = 0; i
  • 当使用我建议的示例时,您是否仍然遇到同样的问题,还是不同的问题?
  • 同样的问题,但是在休息时,当我尝试查找当前总行数时,我看到类似“无法评估表达式,因为当前方法的代码已优化”。只是有时而已。
  • 哦,我刚刚使用您的方法收到另一个错误,其中 RowCount 为 16,“i”也是 16,它尝试了删除。这很奇怪,因为它不应该尝试它,除非“i”是 15 或更低。
【解决方案3】:

你为什么不把总计数放到一个单独的变量中然后迭代

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

【讨论】:

    【解决方案4】:

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

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

    【讨论】:

      【解决方案5】:

      当你从一个数组中移除一个元素时,它会被重建;将剩余元素向上移动 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");
      

      【讨论】:

        【解决方案6】:

        这里大家的建议我都试过了,还是有错误。

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

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

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2020-09-03
          • 2022-01-23
          • 1970-01-01
          • 2018-12-03
          • 2018-12-30
          • 2023-03-11
          相关资源
          最近更新 更多