2011-10-14 93 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); 
     } 
相关问题