• 我在Web应用程序中创建了一个ConcurrrentDictionary作为应用程序对象。并在 session 之间共享。 (基本上用作存储库。)
  • 有时,任何可用的 session 都会将新项添加到字典中。

  • 只允许管理员查看

    现在,我希望允许管理员列出字典中的所有值,但是管理员将不会添加或删除项目,相反,我将仅提供一种方式,让管理员通过遍历以下内容来读取集合以查看项目这几项。

    (伪)代码看起来像这样:
    foreach (var e in EmployeeCache.Instance.AllEmployees)
    {
         Console.WriteLine(e.Key);
    }
    

    我的问题是:

    如果我遍历项目,那么从中读取ConcurrentDictionary时是否将其锁定?换句话说,ConcurrentDictionary是否已锁定,以便在管理代码只是简单地通过ConcurrentDictionary进行迭代时,其他 session 将无法添加或删除?

    如果未锁定,您能否解释

    如果您认为它没有被锁定,能否简要概述一下它是如何进行的?
    例如,它是否为只读操作创建ConcurrentDictionary的副本,然后允许读取迭代运行-了解不会看到对实际字典的并发更改?

    我正在尝试确定

    我试图了解提供ConcurrentDictionary查看器的影响,管理员可以经常刷新该查看器。 IE。如果他们经常刷新它,可能会影响Web应用程序的性能。由于 session 正在等待对象解锁,因此他们可以添加/删除项目?

    最佳答案

    这是 ConcurrentDictionary.GetEnumerator 的实现方式:

    /// <remarks>
    /// The enumerator returned from the dictionary is safe to use concurrently with
    /// reads and writes to the dictionary, however it does not represent a moment-in-time
    /// snapshot of the dictionary. The contents exposed through the enumerator may contain
    /// modifications made to the dictionary after <see cref="GetEnumerator"/> was called.
    /// </remarks>
    public IEnumerator<KeyValuePair<TKey, TValue>> GetEnumerator()
    {
        Node[] buckets = m_tables.m_buckets;
    
        for (int i = 0; i < buckets.Length; i++)
        {
            // The Volatile.Read ensures that the load of the fields of 'current'
            // doesn't move before the load from buckets[i].
            Node current = Volatile.Read<Node>(ref buckets[i]);
    
            while (current != null)
            {
                yield return new KeyValuePair<TKey, TValue>(current.m_key, current.m_value);
                current = current.m_next;
            }
        }
    }
    

    如您所见,该迭代是无锁的,并且仅生成一个不变的结构(KeyValuePair),该结构将在每次迭代时返回给调用者。这就是为什么它不能保证ConcurrentDictionary的实时快照的原因

    这绝对不会在迭代时添加/更新新值上产生性能影响,但是它不能保证您的管理员将看到词典的最新快照。
  • 您可以通过以下方式自己浏览其余的源代码
    http://sourceof.net
  • 您也可以 checkout Simon Cooper的Inside the Concurrent Collections:ConcurrentDictionary
  • Are all of the new concurrent collections lock-free?
  • 关于c# - 遍历ConcurrentDictionary并且仅读取时,ConcurrentDictionary是否被锁定?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/24247029/

    10-09 10:02