ConcurrentDictionary 中的 Keys 集合是否是线程安全的

Nik*_*lay 5 c# concurrency

我必须通过一些键从 ConcurrentDictionary 中删除项目。像这样:

ConcurrentDictionary<SomeClass, string> dict = new ConcurrentDictionary<SomeClass, string>();
//adding some values
var keys = dict.Keys.Where(k => k.Name == "Example");
foreach (var key in keys)
    dict.TryRemove(key, out _);
Run Code Online (Sandbox Code Playgroud)

问题是:我正在枚举何时开始循环的键集合。如果有人同时改变字典怎么办?dict.Keys 是否返回快照?

Bac*_*cks 5

看一下源代码

public ICollection<TKey> Keys
{
    get { return GetKeys(); }
}

private ReadOnlyCollection<TKey> GetKeys()
{
    int locksAcquired = 0;
    try
    {
        AcquireAllLocks(ref locksAcquired);

        int count = GetCountInternal();
        if (count < 0) throw new OutOfMemoryException();

        List<TKey> keys = new List<TKey>(count);
        for (int i = 0; i < _tables._buckets.Length; i++)
        {
            Node current = _tables._buckets[i];
            while (current != null)
            {
                keys.Add(current._key);
                current = current._next;
            }
        }

        return new ReadOnlyCollection<TKey>(keys);
    }
    finally
    {
        ReleaseLocks(0, locksAcquired);
    }
}
Run Code Online (Sandbox Code Playgroud)

它锁定集合并返回密钥副本