线程安全的 foreach 枚举列表

我需要枚举通用 IList

请先 登录 后评论

7 个回答

Patrick

Forech 依赖于集合不会改变的事实。如果您想遍历一个可以更改的集合,请使用正常的 for 构造并准备好非确定性行为。锁定可能是一个更好的主意,具体取决于您在做什么。

请先 登录 后评论
Jason Punyon

没有这样的操作。你能做的最好的就是

<上一页> lock(collection){ foreach (object o in collection){ ... } }
请先 登录 后评论
John Millikin

克隆列表是最简单和最好的方法,因为它可以确保您的列表不会因您而改变。如果列表太大而无法克隆,请考虑在其周围加一个锁,在读取/写入之前必须对其进行锁定。

请先 登录 后评论
jamuraa

将列表包装在一个锁定对象中以进行读写。如果你有一个合适的锁,你甚至可以一次迭代多个读取器,它允许多个并发读取器但也允许单个写入器(当没有读取器时)。

请先 登录 后评论
jan.vdbergh

您的问题是枚举不允许 IList 更改。这意味着您在浏览列表时必须避免这种情况。

我想到了几种可能性:

  • 克隆列表。现在每个枚举器都有自己的副本可以处理。
  • 序列化对列表的访问。使用锁确保在枚举时没有其他线程可以修改它。

或者,您可以编写自己的 IList 和 IEnumerator 实现,以实现所需的并行访问。不过,恐怕这并不简单。

请先 登录 后评论
Jeffrey L Whitledge

所以要求是:你需要通过一个 IList 来枚举

请先 登录 后评论
Community

简单的索引数据结构(如链表、b 树或哈希表)的默认行为是按从第一个到最后一个的顺序进行枚举。在迭代器已经超过该点之后在数据结构中插入一个元素或插入一个迭代器到达后将枚举的元素不会导致问题,并且应用程序可以检测到此类事件并在以下情况下进行处理应用程序需要它。为了检测集合中的变化并在枚举过程中抛出错误,我只能想象某人的(坏)想法,即做他们认为程序员想要的事情。事实上,微软已经修复了他们的集合以正常工作。他们在 .NET 4.0 中调用了他们闪亮的新的完整集合 ConcurrentCollections (System.Collections.Concurrent)。

请先 登录 后评论
  • 16 关注
  • 0 收藏,125 浏览
  • Radu094 提出于 2022-09-27 13:44