簡體   English   中英

清除列表時出現問題<T>

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM