【问题标题】:How to get moment-in-time snapshot of ConcurrentDictionary in C#?如何在 C# 中获取 ConcurrentDictionary 的即时快照?
【发布时间】:2017-05-11 20:27:49
【问题描述】:

MSDN 声明从字典返回的枚举器不代表字典的即时快照。虽然在多线程环境中很少需要它,但如果需要,获取 ConcurrentDictionary 的即时快照的最佳方法是什么?

【问题讨论】:

  • 如何为可以在多个线程上并行更改的集合定义“即时”快照?遍历集合以收集组成它的项目需要时间,并且在此期间它可能已经被修改。这样做并非不可能,但它相当复杂,ConcurrentDictionary 不会这样做。
  • @xxbbcc 请参见GetEnumerator() 代码ConcurrentBag<T>ConcurrentQueue<T>ConcurrentStack<T>,它们都提供了枚举器的即时快照。
  • @ScottChamberlain 您的 BlockignCollection 提案仍然无法及时为您提供快照。在取出一项后,字典的其他用户可能会删除一项(或添加一个新项),从而弄乱您的迭代器。
  • @IvanStoev 对于 ConcurrentDictionary 它没有,对于其他类型它有。这就是斯科特的观点。
  • @Ramy 随意询问课程的开发人员为什么按他们的方式设计它。

标签: c# multithreading concurrentdictionary


【解决方案1】:

只需调用ToArray() 方法即可。

这是source code

    /// <summary>
    /// Copies the key and value pairs stored in the <see cref="ConcurrentDictionary{TKey,TValue}"/> to a
    /// new array.
    /// </summary>
    /// <returns>A new array containing a snapshot of key and value pairs copied from the <see
    /// cref="ConcurrentDictionary{TKey,TValue}"/>.</returns>
    [SuppressMessage("Microsoft.Concurrency", "CA8001", Justification = "ConcurrencyCop just doesn't know about these locks")]
    public KeyValuePair<TKey, TValue>[] ToArray()
    {
        int locksAcquired = 0;
        try
        {
            AcquireAllLocks(ref locksAcquired);
            int count = 0;
            checked
            {
                for (int i = 0; i < m_tables.m_locks.Length; i++)
                {
                    count += m_tables.m_countPerLock[i];
                }
            }

            KeyValuePair<TKey, TValue>[] array = new KeyValuePair<TKey, TValue>[count];

            CopyToPairs(array, 0);
            return array;
        }
        finally
        {
            ReleaseLocks(0, locksAcquired);
        }
    }

【讨论】:

  • 您甚至可以将其链接到foo.ToArray().ToDictionary(x=&gt;x.Key, x=&gt;x.Value); 以将其恢复为字典形式。 (不要只使用foo.DoDictionary(),否则它将使用.GetEnumerator() 函数而不是.ToArray() 函数作为数据源)
  • 根据您所追求的,.Keys.Values 还会为您提供它们各自值的快照。
猜你喜欢
  • 1970-01-01
  • 2019-05-31
  • 2019-09-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多