//I have collection
private static List<Sport> ChosenSports = new List<Sport>();
//and lock object for it
private static object _lockSports = new object();
//I have checkbox that add or remove collection items
private void CheckBoxSportZone_Checked(object sender, RoutedEventArgs e)
{
var chkZone = sender as CheckBox;
lock (_lockSports)
{
if (chkZone.IsChecked == true)
ChosenSports.Add(chkZone.DataContext as Sport);
else if (chkZone.IsChecked == false)
ChosenSports.Remove(chkZone.DataContext as Sport);
}
}
//And method that uses that collection
private IEnumerable<Sport> FilterSports(HashSet<Sport> sports)
{
lock (_lockSports)
return sports. Where(x => ChosenSports.Contains(x));
}
当我检查checkBox Filter方法抛出
时未处理的类型&#39; System.ArgumentOutOfRangeException&#39; 发生在mscorlib.dll
其他信息:指数超出范围。必须是非负面的 并且小于集合的大小。
看起来我在检查收集时标记了ChechBox。但是我使用了锁定关键字,所以它应该是安全的,不是吗?
答案 0 :(得分:4)
此代码:
private IEnumerable<Sport> FilterSports(HashSet<Sport> sports)
{
lock (_lockSports)
return sports. Where(x => ChosenSports.Contains(x));
}
仅锁定Linq表达式的实例化。在实际枚举表达式的时候,锁将会消失。
您应该通过调用ChosenSports
来使.ToArray()
集合在锁内迭代(并返回枚举的副本):
private IEnumerable<Sport> FilterSports(HashSet<Sport> sports)
{
lock (_lockSports)
return sports.Where(x => ChosenSports.Contains(x)).ToArray();
}