c# - 在c#中,如何在多线程环境下迭代IEnumerable

标签 c# multithreading dictionary concurrency ienumerable

我在这种情况下有一个很大的字典被一个线程以相当高的频率随机更新,并且有另一个线程试图拍摄字典的快照以保存为历史。 我目前正在使用这样的东西:

Dictionary<string, object> dict = new Dictionary<string, object>();
var items = dict.Values.ToList();

这在大多数情况下工作正常,除了它偶尔会抛出:

System.InvalidOperationException: Collection was modified; enumeration operation may not execute.

我明白为什么会这样,但我不知道我该怎么做才能避免集合修改错误。

迭代此类集合的最佳方法是什么?

我也试过 ConcurrentDictionary,但没有成功。 为什么? ConcurrentDictionary 线程是否仅在项目级别安全?

最佳答案

根据 the docs您应该能够使用 ConcurrentDictionary 的 GetEnumerator() 方法来获取线程安全的迭代器。

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 GetEnumerator was called.

由于您正在处理并发线程,因此在一致性方面进行一些权衡并不奇怪,但我希望这种方法比其他答案中给出的蛮力方法阻塞更少。如果您尝试过,这将不会奏效:

var items = concurrentDict.Items.ToList();

但它应该适用于

var items = concurrentDict.GetEnumerator();

或者您可以直接引用迭代器:

foreach(var item in concurrentDict)
{
    valueList.Add(item.Value);
}

关于c# - 在c#中,如何在多线程环境下迭代IEnumerable,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44403020/

相关文章:

java - 为什么Throwable::printStackTrace持有PrintStream锁并导致回退死锁

Python反向字典项目顺序

c# - C++/CLI 性能与 native C++ 相比?

android - 从应用程序缓存加载时 ListView 滞后

c# - 忽略数据模型中的属性,同时将它们保留在 EF Core 迁移中

java - 离开 Activity 时 Android 如何处理后台线程?

python - 在 Python 中递归添加字典

c# - 将两个列表映射到 C# 中的字典中

c# - 为什么要使用 HttpClient 进行同步连接

c# - RegEx 帮助 - 从 JavaScript 转换为 C#