为什么SynchronizedCollection<T>
在IEnumerable.GetEnumerator()
IEnumerator IEnumerable.GetEnumerator()
{
return this.items.GetEnumerator();
}
隐式实现确实获得了对SyncOb的锁定(由反射器验证)。
在此集合的foreach循环期间可能会出现问题。一个线程可能已经获得了锁定而另一个可能尝试使用foreach读取它?
答案 0 :(得分:4)
因为类无法知道何时使用迭代器完成客户端代码。这就是System.Collection类上的MSDN Library文档始终警告迭代集合不是线程安全的原因之一。
虽然他们似乎忘了在SynchronizedCollection的文章中提到它。具有讽刺意味......
答案 1 :(得分:1)
当某人使用迭代器时修改集合无论如何都是并发冲突。
你的选择是什么?在获取迭代器时锁定集合,在解析迭代器之前不解锁它?
答案 2 :(得分:1)
我将继续说这可能是实施中的错误( ed:或至少是不一致)。 Reflector精确显示您所看到的内容,除了SyncRoot
之外,每个其他显式实现都会锁定IEnumerable.GetEnumerator()
给定的内容。
也许你应该在Microsoft Connect提交一张票。
我认为隐式GetEnumerator()
方法调用lock
的原因是因为List<T>.GetEnumerator()
创建了一个新的Enumerator<T>
,它依赖于列表中的私有字段_version
。虽然我同意其他海报,但我没有看到锁定GetEnumerator()
调用的用法,但由于Enumerator<T>
的构造函数依赖于非线程安全字段,因此锁定是有意义的。或者至少与隐式实现保持一致。