繁体   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