Die Auflistung wurde geändert, der Enumerationsvorgang kann nicht ausgeführt werden
Habe ich multithreads Anwendung, und ich bekomme diese Fehlermeldung
************** Exception Text **************
System.InvalidOperationException: Collection was modified; enumeration operation may not execute.
at System.ThrowHelper.ThrowInvalidOperationException(ExceptionResource resource)
at System.Collections.Generic.List`1.Enumerator.MoveNextRare()
at System.Collections.Generic.List`1.Enumerator.MoveNext()
...
Wahrscheinlich habe ich problem mit meiner Sammlung, weil in einem thread Las ich, meine Sammlung und meine in einem anderen thread, die ich ändern Sammlung.
public readonly ObservableCollectionThreadSafe<GMapMarker> Markers = new ObservableCollectionThreadSafe<GMapMarker>();
public void problem()
{
foreach (GMapMarker m in Markers)
{
...
}
}
Ich versuche zu sperren, die Sammlung mit diesem code, funktioniert aber nicht.
public void problem()
{
lock(Markers)
{
foreach (GMapMarker m in Markers)
{
...
}
}
}
Irgendwelche Ideen um dieses problem zu beheben?
- Problem ist mit dem code in der
foreach
, poste es bitte. - Sie nicht ändern Sammlung, während die Schleife mit foreach
Du musst angemeldet sein, um einen Kommentar abzugeben.
Dies ist ein ziemlich häufiger Fehler - ändern einer collection während Iteration es mit
foreach
im Auge behalten, dassforeach
verwendet readonlyIEnumerator
Instanz.Versuchen, um eine Schleife durch die Sammlung mit
for()
mit einem zusätzlichen index überprüfen, so dass, wenn der index außerhalb der Grenzen, die Sie würde in der Lage sein, um zusätzliche Logik zu behandeln. Sie können auch die LINQ istCount()
als weitere Bedingung zum beenden der Schleife durch die Auswertung derCount
Wert jedes mal, wenn die zugrunde liegende enumeration implementiert nichtICollection
:Wenn
Markers
implementiertIColletion
- lock auf SyncRoot:Verwenden
for()
:Vielleicht finden Sie diesen Beitrag hilfreich: Wie foreach-Schleifen arbeiten, die in C#?
IndexOutOfRange
AusnahmeObservableCollectionThreadSafe
ist eine eigene Sammlung Klasse, bitte zeigen Sie code zum Hinzufügen/Entfernen, BTW haben Sie eine Sperrethis.SyncRoot
innen-Add/Remove-Methoden?lock(this.SyncRoot) { this.Add(item); }
innerhalb einer ObservableCollectionThreadSafe Klasse, das gleiche fürRemove()
this.syncRoot = (this as ICollection).SyncRoot
seitICollection
explizit umgesetzt werdenGesperrt werden müssen, sowohl auf das Lesen und das schreiben-Seite. Ansonsten einer der threads, die nicht wissen, über das Schloss und versuchen zu Lesen/ändern der Sammlung, während der andere zu verändern/Lesen (bzw.) mit der Sperre
Versuchen zu Lesen, einen Klon Ihrer Sammlung
dadurch wird eine neue Kopie von Ihrer Sammlung, die nicht beeinflusst werden durch einen anderen thread, aber kann dazu führen, ein performance-Problem bei der riesigen Sammlung.
Also ich denke es wird besser sein, wenn Sie Verriegelte die Sammlung beim Lesen und schreiben Prozesse.
.Copy
aber kann es zu einem performance-Problem.Können Sie verwenden Sie eine foreach-aber Sie haben zu werfen, die Sammlung auf eine Liste und verwenden Sie den Punkt-operator zum Zugriff auf das Verhalten von Methoden.
Beispiel: Marker.Tolist().ForEach(ich => ich.DeleteObject())
Nicht ganz sicher, was du tust mit deiner Sammlung. Mein Beispiel ist vorausgesetzt, Sie wollte nur, um zu löschen Sie alle Elemente aus der Auflistung, aber es kann angewendet werden, um jedes Verhalten, das Sie versuchen zu tun, mit Ihrer Sammlung.
Ich löste dieses problem, indem
statt