Ich habe Multithread-Anwendung und ich bekomme diesen Fehler
%Vor%Ich habe wahrscheinlich Probleme mit meiner Sammlung, weil ich in einem Thread meine Sammlung lese und in einem anderen Thread die Sammlung ändere.
%Vor%Ich versuche, die Sammlung mit diesem Code zu sperren, funktioniert aber nicht.
%Vor%Irgendwelche Ideen, um dieses Problem zu beheben?
Dies ist ein ziemlich verbreiteter Fehler - wenn Sie eine Sammlung ändern, während Sie sie mit foreach
iterieren, denken Sie daran, dass foreach
readonly IEnumerator
instance verwendet.
Probieren Sie Schleife durch die Sammlung mit for()
mit extra Index überprüfen, so wenn Index ist außerhalb des Bereichs - Sie könnten zusätzliche Logik anwenden, um dies zu behandeln, auch als Schleife Exit-Bedingung können Sie verwenden LINQ Count()
, die würde Bewerten Sie den Zählwert jedes Mal, wenn die zugrunde liegende Enumeration ICollection
nicht implementiert:
Wenn Markers
implementiert IColletion
- Sperre auf SyncRoot:
Verwenden Sie for()
:
Findet diesen Beitrag möglicherweise nützlich: Wie funktionieren foreach-Schleifen in C #?
Versuchen Sie, einen Klon Ihrer Sammlung zu lesen
%Vor%Dies erstellt eine neue Kopie Ihrer Sammlung, die nicht von einem anderen Thread betroffen ist, aber im Falle einer umfangreichen Sammlung zu einem Leistungsproblem führen kann.
Ich denke, es ist besser, wenn Sie die Sammlung während des Lese- und Schreibvorgangs sperren.
Sie können eine Foreach verwenden, aber Sie müssen die Sammlung in eine Liste umwandeln und den Punktoperator verwenden, um auf die Verhaltensmethoden zuzugreifen.
Beispiel: Markers.Tolist (). ForEach (i = & gt; i.DeleteObject ())
Nicht ganz sicher, was Sie mit Ihrer Sammlung machen. In meinem Beispiel gehen wir davon aus, dass Sie nur alle Elemente aus der Sammlung löschen möchten, sie können jedoch auf jedes Verhalten angewendet werden, das Sie mit Ihrer Sammlung durchführen möchten.
Ich würde vorschlagen, AsyncCommand
zu verwenden, weil AsyncCommand
entweder verwendet wird oder nicht, während lock(Markers)
die Reentrancy erlaubt. (Siehe Ссылка ):
Mit AsyncLock
können Sie auch Thread.Sleep
durch seine asynchrone Entsprechung await Task.Delay(TimeSpan.FromSeconds(1))
Tags und Links c# multithreading enumerator