C# 查找如何修改foreach集合

C# 查找如何修改foreach集合,c#,function,loops,for-loop,C#,Function,Loops,For Loop,如何找出哪个函数或目标正在修改多线程应用程序中foreach循环中的项 我不断收到错误“集合已修改;枚举操作可能无法执行”。我没有在for循环中删除或添加任何项目到通用列表。 我想知道它是如何被修改的。 最好的方法是什么 谢谢做到这一点的最好方法是不要将集合公开给许多可能会改变它的类。将其私有化为一个特定类,则只有该类的方法才可能更改它 否则,您需要从集合类创建一个派生类,并重写可以更新集合的所有方法。在所有重写处设置断点。是否可以将全局集合的内容复制到范围更紧的变量,以保护外部对数据的干预?这

如何找出哪个函数或目标正在修改多线程应用程序中foreach循环中的项

我不断收到错误“集合已修改;枚举操作可能无法执行”。我没有在for循环中删除或添加任何项目到通用列表。 我想知道它是如何被修改的。 最好的方法是什么


谢谢

做到这一点的最好方法是不要将集合公开给许多可能会改变它的类。将其私有化为一个特定类,则只有该类的方法才可能更改它


否则,您需要从集合类创建一个派生类,并重写可以更新集合的所有方法。在所有重写处设置断点。

是否可以将全局集合的内容复制到范围更紧的变量,以保护外部对数据的干预?

这不是一个直接的答案,只是一个可能有帮助的建议-在多线程情况下,集合可能会在迭代过程中被修改,我通常使用ToArray方法为迭代创建列表快照:

foreach (object x in list.ToArray()) ...

将集合替换为,将事件附加到修改并在调试器中对其进行中断(或捕获堆栈跟踪等)。

您应该能够设置一个异常断点,然后只需检查每个线程以查看哪个线程修改了集合。在任何情况下,如果集合在多个线程之间共享,则需要对其进行适当的同步。

您可能需要为此试用该类。还有一些示例可以使此线程安全。

您也可以尝试更改集合的类名,以查看所有引用的位置。

等一下-我想我们都没有抓住要点

集合类不是线程安全的。如果集合被多个线程访问而没有线程锁定,则需要修复该问题。这是一个特别隐蔽的问题,因为它会在99.999%的时间内正常工作[编辑或抛出可预测的异常],在0.001%的时间内,它会做一些完全不可预测且几乎不可能重现的事情

一种简单的方法是在任何代码访问集合的每个地方使用lock{}语句。这可能有点过分,但这是最安全的计划。对于迭代,您可以在整个循环周围设置一个锁,或者如果您不想阻止其他那么长的线程,只需将其锁定到足以生成快照的时间:

object[] snap;
lock (list)
{
   snap = list.ToArray();
}
foreach (object x in snap) ...

这个包含foreach循环的类是泛型列表的一部分。除此之外,泛型列表中该类的每个实例都在单独的Thread中运行,因此不需要并发来解决此问题。在循环中调用的方法可能导致修改集合的代码。是的,绝对是。我不认为异常可能是线程问题,因为它一直在发生。我只是说缺少线程锁定是非常令人担忧的,因为它可能“似乎”起作用,但如果多个线程确实在没有锁定的情况下访问集合,那就有点定时炸弹了。