2011-10-14 92 views
1

我需要幫助。我正在與一個數據列表工作,並突然發現這個錯誤。收藏已修改;枚舉操作可能不會執行。 C#

'System.InvalidOperationException' 類型的未處理的異常出現在mscorlib.dll

其他信息:集合已修改;枚舉操作可能不會執行。

這是它顯示了異常的代碼......

foreach (PC_list x in onlinelist) { 
    if ((nowtime.Subtract(x.time)).TotalSeconds > 5) { 
    Invoke(new MethodInvoker(delegate { 
     index = Main_ListBox.FindString(x.PcName); 
     if(index != ListBox.NoMatches) 
     Main_ListBox.Items.RemoveAt(index); 
    })); 
    onlinelist.Remove(x); 
    //Thread.Sleep(500); 
    } 
} 

​​

注:

  • onlinelist是一個ArrayList
  • nowtime和x.time是DateTime。

調用堆棧

mscorlib.dll!System.Collections.ArrayList.ArrayListEnumeratorSimple.MoveNext() + 0x122 bytes  
BlueBall.exe!BlueBall.BlueBall.clean_arraylist() Line 74 + 0x1a8 bytes C# 
BlueBall.exe!BlueBall.BlueBall.server() Line 61 + 0x8 bytes C# 
mscorlib.dll!System.Threading.ThreadHelper.ThreadStart_Context(object state) + 0x63 bytes 
mscorlib.dll!System.Threading.ExecutionContext.Run(System.Threading.ExecutionContext executionContext, System.Threading.ContextCallback callback, object state, bool ignoreSyncCtx) + 0xb0 bytes  
mscorlib.dll!System.Threading.ExecutionContext.Run(System.Threading.ExecutionContext executionContext, System.Threading.ContextCallback callback, object state) + 0x2c bytes  
mscorlib.dll!System.Threading.ThreadHelper.ThreadStart() + 0x44 bytes 
[Native to Managed Transition] 

回答

14
foreach (PC_list x in onlinelist) 
{    
    onlinelist.Remove(x); // cannot do this 
} 

這是問題的心臟。當您在foreach中迭代它時,無法從集合中刪除項目。您的選擇是在循環之前創建列表的本地副本,循環遍歷副本並從原始副本中刪除。或者您可以在之後保留一個單獨的項目列表以刪除您完成原始循環。或者你也可以切換到for循環和迭代它倒退,它允許你從年底你去刪除項目。

當你在這裏,如果你不堅持用C#的工作1/.NET 1.1/Visual Studio 2003中,你可能要考慮從ArrayList切換到強List<T>,其中T是對象的類型集合。在你的情況下,這將是一個List<PC_list>。你可以在System.Collections.Generic.List<T>找到它。

而且,由於你的問題被標記multithreading,這也將是一個聰明的主意諮詢collections built with concurrency in mind

0

呀,你的邏輯被打破了。你問的迭代器在列表中x後移動到下一個對象,但你已刪除從列表x,所以沒有這樣的事情。有很多解決方法,而傳統的方式來做到這一點是在循環的頂部去除以前對象。 (這僅適用於那些不上清除重新組織集合。)

+1

這不是這麼回事。在foreach循環中,不能從列表中刪除任何項目。 – phoog

4

你不能在foreach塊修改onlinelist。這就是你得到這個錯誤的原因。 試試這個:

ArrayList RemoveList = new ArrayList(); 
foreach (PC_list x in onlinelist) 
      { 
       if ((nowtime.Subtract(x.time)).TotalSeconds > 5) 
       { 
        Invoke(new MethodInvoker(delegate 
        { 
         index = Main_ListBox.FindString(x.PcName); 
         if(index != ListBox.NoMatches) 
          Main_ListBox.Items.RemoveAt(index); 
        })); 

        RemoveList.Add(x); 
        //Thread.Sleep(500); 
       } 
      } 
foreach (PC_list x in RemoveList) 
     { 
       onlinelist.Remove(x); 
     } 
相關問題