[英]Problem with clearing a List<T>
當我清除System.Collections.Generic.List<T>
時,我不知道為什么我有一個IndexOutOfRangeException
。 這有意義嗎?
List<MyObject> listOfMyObject = new List<MyObject>();
listOfMyObject.Clear();
如果多個線程同時訪問列表,通常會發生這種情況。 如果一個線程刪除一個元素而另一個線程調用Clear(),則可能發生此異常。
在這種情況下,“答案”是適當地同步它,鎖定所有列表訪問。
編輯:
為了處理這個問題,最簡單的方法是將列表封裝在自定義類中,並公開所需的方法,但需要鎖定。 您需要為改變集合的任何東西添加鎖定。
這將是一個簡單的選擇:
public class MyClassCollection
{
// Private object for locking
private readonly object syncObject = new object();
private readonly List<MyObject> list = new List<MyObject>();
public this[int index]
{
get { return list[index]; }
set
{
lock(syncObject) {
list[index] = value;
}
}
}
public void Add(MyObject value)
{
lock(syncObject) {
list.Add(value);
}
}
public void Clear()
{
lock(syncObject) {
list.Clear();
}
}
// Do any other methods you need, such as remove, etc.
// Also, you can make this class implement IList<MyObject>
// or IEnumerable<MyObject>, but make sure to lock each
// of the methods appropriately, in particular, any method
// that can change the collection needs locking
}
您確定該代碼會引發異常嗎? 我有
using System.Collections.Generic;
class MyObject { }
class Program {
static void Main(string[] args) {
List<MyObject> listOfMyObject = new List<MyObject>();
listOfMyObject.Clear();
}
}
而且我沒有例外。
你的現實生活中的例子更復雜嗎? 也許你有多個線程同時訪問列表? 我們能看到堆棧跟蹤嗎?
List<T>.Clear
非常簡單。 使用反射器:
public void Clear() {
if (this._size > 0) {
Array.Clear(this._items, 0, this._size);
this._size = 0;
}
this._version++;
}
在列表已經為空的情況下,這不會拋出異常。 但是,如果要修改另一個線程上的列表, Array.Clear
可能會拋出IndexOutOfRangeException
異常。 因此,如果另一個線程從列表中刪除一個項目,那么this._size
(要清除的項目數)將太大。
文檔沒有提到此方法拋出的任何異常,您的問題可能在其他地方。
List<T>.Clear
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.