1 回答

TA貢獻(xiàn)1868條經(jīng)驗(yàn) 獲得超4個(gè)贊
錯(cuò)誤的根本原因是List<T>構(gòu)造不是線程安全的。
讓我們看看在構(gòu)造 new 時(shí)會(huì)發(fā)生什么SynchronizedReadOnlyCollection。異常發(fā)生在以下行:
return new SynchronizedReadOnlyCollection<int>(testlist.SyncRoot, testlist);
正如異常 StackTrace 告訴我們的那樣,List<T>..ctor在構(gòu)建過(guò)程中涉及到:
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)
構(gòu)造函數(shù)中的以下片段List<T>顯示了錯(cuò)誤發(fā)生的位置。代碼是從MS 參考源中復(fù)制的,我清理了代碼中不需要的部分以便于閱讀。請(qǐng)注意,在注釋 (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在構(gòu)造 new 時(shí),可以通過(guò)鎖定修改輕松解決該問(wèn)題SynchronizedReadOnlyCollection。
public SynchronizedReadOnlyCollection<int> pubReadOnlyProperty
{
get
{
lock (testlist.SyncRoot)
{
return new SynchronizedReadOnlyCollection<int>(testlist.SyncRoot, testlist);
}
}
}
- 1 回答
- 0 關(guān)注
- 147 瀏覽
添加回答
舉報(bào)