2010-12-15 6 views
6

ループ中に行を削除しようとすると、次のエラーが発生します。列挙中にデータテーブルの行を削除する問題

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

     } 
    } 
} 

}

任意の助けを大幅に逆forループを使用、代わりforeachを用いる

答えて

14

を理解されるであろう:実際の行を削除

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

行の元のコレクションを変更します。ほとんどの列挙子は、列挙の途中でソースシーケンスが変更されたことを検出した場合に爆発するように設計されています。変更されている何かに渡ってforeachという奇妙な可能性をすべて処理しようとするのではなく、それを禁止する。

+0

手袋のように! thanx – hikizume

3

foreach内のコレクションを変更することはできません。

代わりに、forというループを使用してください。

3

要素リストのループから要素を削除するには、forループを使用し、最後の要素から開始して最初の要素に移動します。あなたの例では

int t_size = table.Rows.Count -1; 

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

編集:十分に迅速ではない:)また

+0

別の 't_size'変数にポイントがありません。 – SLaks

+0

@SLaks:いいえ、それはちょうどより明確になります:) – LaGrandMere

+0

@SLaks私はそれがあなたのコメントよりも多くのポイント、 –

0

、あなたが行を処理し、逆ループはあなたのために動作しないという順序に依存している場合。削除する行をリストに追加してから、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())); 
} 
0

どういうわけかremoveJob(id)は多分データバインディングを経て、(私はそれは後者だろうと思いメソッドの名前からtable.RowsまたはJobsDS.Tables、)あなたの列挙IEnumerablesのいずれかを変更します。

内側foreach内から外側foreachに列挙された要素を削除しているようですので、後方にforが直接動作するかどうかはわかりません。 removeJob(id)で何が起こったかについての情報なしでは、それを伝えるのは難しいです。

関連する問題