2016-06-10 8 views
0
//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)); 
} 

Wenn i checkBox Filter-Methode throw überprüfenArgumentOutOfRangeException auf veränderte colletion

Eine nicht behandelte Ausnahme des Typs 'System.ArgumentOutOfRangeException' in mscorlib.dll

Zusätzliche Informationen aufgetreten: Index war außerhalb des Angebot. Muss nicht-negativ sein und weniger als die Größe der Sammlung.

Sieht aus wie ich ChechBox in der Zeit der Überprüfung der Sammlung markieren. Aber ich benutze das Lock-Schlüsselwort, also sollte es sicher sein, oder?

+2

Nur aus Neugier ... es, wenn nicht funktioniert Sie refaktorieren, so dass Sie kein Lambda in Ihrem Schloss verwenden, dh es zu einem Block anstatt einer einzelnen Linie machen und eine Schleife erstellen, um die resultierende Sammlung zu erstellen? –

Antwort

4

Dieser Code:

private IEnumerable<Sport> FilterSports(HashSet<Sport> sports) 
{ 
    lock (_lockSports) 
     return sports. Where(x => ChosenSports.Contains(x)); 
} 

sperrt nur die Instanziierung des Ausdrucks Linq. Die Sperre ist zu der Zeit weggegangen, zu der der Ausdruck tatsächlich aufgezählt wird.

Sie sollten wahrscheinlich dazu führen, die ChosenSports Sammlung innerhalb des Schlosses iteriert wird (und eine Kopie der Aufzählung zurück), durch .ToArray() Aufruf wie folgt:

private IEnumerable<Sport> FilterSports(HashSet<Sport> sports) 
{ 
    lock (_lockSports) 
     return sports.Where(x => ChosenSports.Contains(x)).ToArray(); 
} 
+2

Richtig, darauf habe ich in meinem Kommentar unter der Frage angespielt. –

+0

@roryap Ja, ich denke, das ist das Problem. Es ist etwas, das mich in der Vergangenheit gebissen hat! –

+0

Danke, jetzt läuft es wie am Schnürchen –

Verwandte Themen