迭代集合而不会看到“集合已修改,枚举无法继续...”的最佳方法

时间:2013-12-13 23:50:51

标签: c# .net vb.net collections

我最近遇到了同样的问题,我在客户端应用程序上有一个集合,我不断用它来更新UI。可以通过服务器推送随时修改集合,这有时会导致异常“由于集合已被修改,枚举无法继续”。我已经使用了各种策略来解决这个问题,例如捕获错误并重新执行代码(感觉垃圾)以及使用不一定锁定集合的synclock(我认为)。

我确定这不是一个新问题,我想知道其他开发者是如何解决这个问题的。

3 个答案:

答案 0 :(得分:1)

如果数据不是太大,我想在枚举时冻结集合:

foreach(var item in new List<ItemType>(collection))
{
    ...
}

答案 1 :(得分:1)

你的问题有两个部分,真的。一个是对可变集合的迭代,但隐藏的复杂性使您的UI与可变集合保持同步。对于小型集合和性能不会让我陷入困境的领域,我会在foreach的集合末尾抛出一个.ToList()。

foreach(var item in collection.ToList())

这样,它会迭代一个新创建的集合,而不是一直在变化的基本集合。

但是,对于UI同步,您需要检查迭代后是否没有更改,这是一个整体'关注程度......

答案 2 :(得分:0)

由于您在迭代集合时似乎无法锁定服务器更改,因此提出了几点建议:

  • 使用for (...)while (...)代替foreach (...),以避免枚举器的“集合被修改”异常。请注意,您需要处理对集合的更改,例如在每次迭代时重新检查集合大小。
  • 如果可能,只更新已修改项目的用户界面。 “服务器推送”是什么意思?如果您的客户端应用程序可以侦听来自服务器的有关已修改项目(包括其索引/ ID)的通知,那么您只需使用上述方法迭代集合一次(初始UI加载)。