我需要帮助。我正在和一个arraylist一起工作,突然间我得到了这个错误。
mscorlib.dll中出现未处理的“System.InvalidOperationException”类型异常
其他信息:收集已修改;枚举操作可能无法执行。
这是显示异常的代码......
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);
}
}
其中
public class PC_list {
public string PcName;
public string ip;
public string status;
public string NickName;
public DateTime time;
}
注意:
调用堆栈
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]
答案 0 :(得分:15)
foreach (PC_list x in onlinelist)
{
onlinelist.Remove(x); // cannot do this
}
这是问题的核心。当您在foreach
中对项目进行迭代时,无法从集合中删除该项目。您可以选择在循环之前制作列表的本地副本,循环复制并从原始文件中删除。或者,您可以保留单独的项目列表,以便在完成原始循环后删除。或者您可以切换到for
循环并向后迭代它,这样您就可以随时从 end 中删除项目。
当你在这里时,如果你不使用C#1 / .NET 1.1 / Visual Studio 2003,你可能要考虑从ArrayList
切换到更强List<T>
,其中{ {1}}是集合中对象的类型。在您的情况下,那将是T
。您可以在List<PC_list>
找到它。
由于您的问题被标记为System.Collections.Generic.List<T>
,因此咨询collections built with concurrency in mind也是明智之举。
答案 1 :(得分:4)
您无法修改foreach块中的在线列表。这就是您收到此错误的原因。 试试这个:
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);
}
答案 2 :(得分:0)
是的,你的逻辑被打破了。您要求迭代器移动到列表中x
之后的下一个对象,但您已从列表中删除x
,因此没有这样的事情。有很多变通方法,但传统的方法是删除循环顶部的之前的对象。 (这仅适用于未在删除时重新组织的集合。)