C# 4.0 在lambda.where上修改了C#集合异常

C# 4.0 在lambda.where上修改了C#集合异常,c#-4.0,exception,collections,lambda,enumeration,C# 4.0,Exception,Collections,Lambda,Enumeration,我有以下代码: var actionsToExecute = _messagesToExecute.Where(m => m.CanExecute).ToList(); 它99%的时间运行良好,但偶尔会崩溃,但以下情况除外: Collection was modified; enumeration operation may not execute 我有点迷路了,因为它看起来有点随机。这是方法中的第一行。什么可能导致lambda表达式引发此异常?它与线程有关。这似乎是网站代码。如果在.

我有以下代码:

var actionsToExecute = _messagesToExecute.Where(m => m.CanExecute).ToList();
它99%的时间运行良好,但偶尔会崩溃,但以下情况除外:

Collection was modified; enumeration operation may not execute

我有点迷路了,因为它看起来有点随机。这是方法中的第一行。什么可能导致lambda表达式引发此异常?

它与线程有关。这似乎是网站代码。如果在.ToList()执行时,访问站点的另一个人修改了该私有变量,则会发生异常

解决方案是使用threadsafe集合,但这并不是最佳选择,因为如果许多人正在读/写它,他们一次只能做一个或多个


我有一个类似的问题,但枚举不是关键的,可以跳过或重复,因此我实现了自己的枚举器,它不会检查是否已修改。

您需要在对_messagesToExecute的所有引用周围使用lock(),或者,您可以使用System.Collections.Concurrent中的某些内容,它处理内部锁定集合的问题

e、 g

然后,每当您更新列表时:

lock(m_lock){
  _messagesToExecute.Add(item);
}
lock(m_lock){
    var actionsToExecute = _messagesToExecute.Where(m => m.CanExecute).ToList();
}
然后当你拿出清单时:

lock(m_lock){
  _messagesToExecute.Add(item);
}
lock(m_lock){
    var actionsToExecute = _messagesToExecute.Where(m => m.CanExecute).ToList();
}

你在穿线吗?也就是说,是否有其他线程可能正在修改_messagesToExecute?这不是网站代码,但您是对的,它用于线程。我把它想下来了,所以在调用此方法时无法更改它。我会再检查一遍,谢谢。