是List <T> .Contains()一个Threadsafe调用 - C#

ade*_*825 11 c# thread-safety

我的理解是,如果您在C#中使用通用列表(List),它可以支持多个并发读取器,但只能支持一个编写器.当您在混合中引入编写器时,还必须提供同步构造以使操作线程安全.

List.Contains被认为是一个读操作吗?换句话说,如果我调用此方法,我是否需要担心作者可能同时写入此列表?

Jon*_*eet 23

是的你应该.基本上,如果列表可能同时用于写入,我会同步任何操作.

通常我发现集合分为两类 - 一类是创建,初始化然后再也没有改变(线程安全),另一类是随时间变化的(不是线程安全的,锁定所有访问).

  • 在你实例化一个,填充它,再也不再使用它的情况下,我发现将它包装在ReadOnlyCollection <T>()中是有帮助的.它不会阻止使用者改变集合中的基础项,但如果您丢弃对原始列表的引用,则迭代是安全的. (5认同)

Eri*_*bal 5

如果你使用 Reflector 来检查代码,你会得到这样的结果:

public bool Contains(T item)
    {
        if (item == null)
        {
            for (int j = 0; j < this._size; j++)
            {
                if (this._items[j] == null)
                {
                    return true;
                }
            }
            return false;
        }
        EqualityComparer<T> comparer = EqualityComparer<T>.Default;
        for (int i = 0; i < this._size; i++)
        {
            if (comparer.Equals(this._items[i], item))
            {
                return true;
            }
        }
        return false;
    }
Run Code Online (Sandbox Code Playgroud)

如您所见,这是对项目的简单迭代,这绝对是“读取”操作。如果您仅将它用于读取(并且不会改变项目),则无需锁定。如果您开始在单独的线程中修改列表,那么您绝对需要同步访问。