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 關注
- 139 瀏覽
添加回答
舉報