C# 即使集合已锁定,foreach也会出现InvalidOperationException

C# 即使集合已锁定,foreach也会出现InvalidOperationException,c#,multithreading,collections,C#,Multithreading,Collections,最近,我一直在尝试使用多线程使我的一个老项目工作,显然,收集是乐趣的一部分。问题在于,一位代码不断随机崩溃,虽然不经常发生,但仍然足够明显: Monde是一个SynchronizedCollection,我正在锁定它以防止同时写入,但它仍然在抱怨它。这有什么我遗漏的吗 编辑:我知道SynchronizedCollection类只会在创建枚举期间自动锁定,因此简单的foreach是不够的,这就是为什么我将整个循环包含在一个锁块中。问题在于,当线程在锁块内时,集合会以某种方式被修改,这是不应该发生的

最近,我一直在尝试使用多线程使我的一个老项目工作,显然,收集是乐趣的一部分。问题在于,一位代码不断随机崩溃,虽然不经常发生,但仍然足够明显:

Monde是一个SynchronizedCollection,我正在锁定它以防止同时写入,但它仍然在抱怨它。这有什么我遗漏的吗

编辑:我知道SynchronizedCollection类只会在创建枚举期间自动锁定,因此简单的foreach是不够的,这就是为什么我将整个循环包含在一个锁块中。问题在于,当线程在锁块内时,集合会以某种方式被修改,这是不应该发生的


此外,.NET 4并发API下的所有类都不能满足我的所有需求,因此如果我不想使整个代码库变得比现在更复杂,我真的没有选择的余地。

首先,如果您使用SynchronizedCollection,那么您就不需要将其封装在锁中,因为它在引擎盖下使用锁进行操作。第二个SynchronizedCollection来自.Net 2.0时代,如果要移植遗留代码,最好使用System.collections.Concurrent命名空间中的集合。它们更新、更优化,不依赖于锁定和阻塞策略


错误,SynchronizedCollection仅在创建枚举器期间锁定,而在枚举本身期间不锁定。这是有意义的,CLR枚举器模型不允许这样做。我的问题是,即使使用锁,集合也会被修改,这违反了并发性contract@zdimension您能否测试使用SynchronizedReadOnlyCollection而不是SynchronizedCollection是否可以解决问题?更大的问题是您在Physique方法中做了什么?它是否有可能修改集合?我非常清楚,请看我对Siavash答案的评论,这就是为什么我将整个循环包含在锁块中。它应该有效地锁定收藏,但它没有,这就是问题所在Physique做什么?我无法重现这个问题。在我的实验中,锁定SyncRoot成功地防止了SynchronizedCollection程序集System.ServiceModel的任何并发变异。您可以共享一个吗?