在枚举时删除数据表中的行时出现问题

时间:2010-12-15 16:39:00

标签: c# datatable

我尝试在循环时删除一行时出现以下错误。

C#:收藏被修改;枚举操作可能无法执行

我已经做了一段时间的研究了,我在这里看过一些类似的帖子,但我还是找不到合适的答案。

foreach (DataTable table in JobsDS.Tables)
{

  foreach (DataRow row in table.Rows)
  {
    if (row["IP"].ToString() != null && row["IP"].ToString() != "cancelled")
    {
        string newWebServiceUrl = "http://" + row["IP"].ToString() + "/mp/Service.asmx";
        webService.Url = newWebServiceUrl;
        string polledMessage = webService.mpMethod(row["IP"].ToString(), row["ID"].ToString());

        if (polledMessage != null)
        {
            if (polledMessage == "stored")
            {               
                removeJob(id);
            }

        }
    }
}

}

任何帮助将不胜感激

5 个答案:

答案 0 :(得分:14)

不使用foreach,而是使用反向for循环:

for(int i = table.Rows.Count - 1; i >= 0; i--)
{
    DataRow row = table.Rows[i];
    //do your stuff
}

删除行确实会修改原始的行集合。如果大多数枚举器在枚举过程中检测到源序列发生了变化,那么大多数枚举器都会被设计为爆炸 - 而不是试图处理foreach所有变化的奇怪可能性,并且可能会引入非常微妙的错误,它更简单地禁止它更安全。

答案 1 :(得分:3)

您无法修改其周围foreach内的集合。

相反,您应该使用向后for循环。

答案 2 :(得分:3)

如果要从元素列表中的循环中删除元素,诀窍是使用for循环,从最后一个元素开始并转到第一个元素。

在你的例子中:

int t_size = table.Rows.Count -1;

for (int i = t_size; i >= 0; i--)
{
   DataRow row = table.Rows[i];
   // your code ...
}

编辑:不够快:))

答案 3 :(得分:0)

此外,如果您依赖处理行的顺序,并且反向循环不适合您。您可以将要删除的行添加到List中,然后在退出foreach循环后,可以删除添加到列表中的行。例如,

foreach (DataTable table in JobsDS.Tables) 
{ 
  List<DataRow> rowsToRemove = new List<DataRow>();
  foreach (DataRow row in table.Rows) 
  { 
    if (row["IP"].ToString() != null && row["IP"].ToString() != "cancelled") 
    { 
        string newWebServiceUrl = "http://" + row["IP"].ToString() + "/mp/Service.asmx"; 
        webService.Url = newWebServiceUrl; 
        string polledMessage = webService.mpMethod(row["IP"].ToString(), row["ID"].ToString()); 

        if (polledMessage != null) 
        { 
            if (polledMessage == "stored") 
            {                
                //removeJob(id); 
                rowsToRemove.Add(row);
            } 

        } 
    } 
  }
  rowsToRemove.ForEach(r => removeJob(r["ID"].ToString()));
} 

答案 4 :(得分:0)

以某种方式removeJob(id)更改了您枚举的IEnumebles之一(table.RowsJobsDS.Tables,从方法的名称,我猜它将是后者),也许是通过DataBinding。

我不确定向后for是否会直接起作用,因为它似乎是从内部foreach中删除外部foreach中枚举的元素。如果没有关于removeJob(id)中发生的事情的更多信息,很难说清楚。