MSDN表示从ConcurrentDictionary
返回的枚举器并不代表ConcurrentDictionary
的瞬时快照。
虽然在多线程环境中很少需要,但如果有需要,如何获取ConcurrentDictionary
的瞬时快照是最佳方式?
MSDN表示从ConcurrentDictionary
返回的枚举器并不代表ConcurrentDictionary
的瞬时快照。
虽然在多线程环境中很少需要,但如果有需要,如何获取ConcurrentDictionary
的瞬时快照是最佳方式?
只需调用 ToArray()
方法即可。
这是一份源代码:
/// <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=>x.Key, x=>x.Value);
以将其转换为字典形式。(不要只使用 foo.DoDictionary()
,否则它会使用 .GetEnumerator()
函数而不是 .ToArray()
函数作为数据源)。 - Scott Chamberlain.Keys
和.Values
也会为您提供它们各自值的快照。 - xr280xrConcurrentDictionary.Count
属性源代码会等待内部锁解锁后才能继续执行),尽管它不应该,因为您对其进行的是非变异操作。 - Alexander Abakumov
ConcurrentDictionary
也无法做到。 - xxbbccConcurrentBag<T>
,ConcurrentQueue<T>
或ConcurrentStack<T>
的GetEnumerator()
代码,它们都提供了枚举器的瞬时快照。 - Scott Chamberlain