我有以下代码:
var actionsToExecute = _messagesToExecute.Where(m => m.CanExecute).ToList();
它在99%的时间内运行正常,但每隔一段时间就会崩溃,但异常:
Collection was modified; enumeration operation may not execute
我有点失落,因为它似乎有点随机。这是该方法的第一行。什么可能导致lambda表达式抛出此异常?
答案 0 :(得分:1)
它与线程有关。看来这是网站代码。如果在执行.ToList()时,访问该站点的其他人修改了该私有变量,则该异常将发生。
解决方案是使用线程安全集合,但这不是最佳选择,因为如果许多人正在阅读/写入它,他们一次只能做多或少一个。
我遇到了类似的问题,但枚举并不重要,可以跳过或重复,所以我实现了自己的枚举器,不检查它是否被修改。
答案 1 :(得分:1)
您需要在所有对_messagesToExecute的引用周围使用lock(),或者您可以使用System.Collections.Concurrent中的内容来处理内部锁定集合。
e.g。
_messagesToExecute = new ConcurrentBag<TMessage>();
或者你更愿意使用锁定:
static readonly object m_lock = new object();
然后每当您更新列表时:
lock(m_lock){
_messagesToExecute.Add(item);
}
然后当你拿出清单时:
lock(m_lock){
var actionsToExecute = _messagesToExecute.Where(m => m.CanExecute).ToList();
}