1 回答
TA贡献1868条经验 获得超4个赞
错误的根本原因是List<T>构造不是线程安全的。
让我们看看在构造 new 时会发生什么SynchronizedReadOnlyCollection。异常发生在以下行:
return new SynchronizedReadOnlyCollection<int>(testlist.SyncRoot, testlist);
正如异常 StackTrace 告诉我们的那样,List<T>..ctor在构建过程中涉及到:
at System.Collections.Generic.SynchronizedCollection`1.CopyTo(T[] array, Int32 index)
at System.Collections.Generic.List`1..ctor(IEnumerable`1 collection)
at System.Collections.Generic.SynchronizedReadOnlyCollection`1..ctor(Object syncRoot, IEnumerable`1 list)
构造函数中的以下片段List<T>显示了错误发生的位置。代码是从MS 参考源中复制的,我清理了代码中不需要的部分以便于阅读。请注意,在注释 (1) 和 (2) 之间还有其他线程在操作集合:
public List(IEnumerable<T> collection) {
ICollection<T> c = collection as ICollection<T>;
// (1) count is now current Count of collection
int count = c.Count;
// other threads can modify collection meanwhile
if (count == 0)
{
_items = _emptyArray;
}
else {
_items = new T[count];
// (2) SynchronizedCollection.CopyTo is called (which itself is thread-safe)
// Collection can still be modified between (1) and (2)
// No when _items.Count != c.Count -> Exception is raised.
c.CopyTo(_items, 0);
_size = count;
}
}
解决方案
testlist在构造 new 时,可以通过锁定修改轻松解决该问题SynchronizedReadOnlyCollection。
public SynchronizedReadOnlyCollection<int> pubReadOnlyProperty
{
get
{
lock (testlist.SyncRoot)
{
return new SynchronizedReadOnlyCollection<int>(testlist.SyncRoot, testlist);
}
}
}
- 1 回答
- 0 关注
- 115 浏览
添加回答
举报