Ich habe ein Szenario, in dem ich ein Element für die Warteschlange entfernen muss, sobald es verarbeitet wurde. Ich verstehe, dass ich einen Artikel nicht aus einer Sammlung entfernen kann, während ich mich in einer Schleife befinde, aber ich habe mich gefragt, ob da etwas ist könnte mit dem Enumerator usw. gemacht werden ...
Dies ist nur ein einfaches Beispiel, bei dem ein Fehler auftritt "Die Sammlung wurde geändert, nachdem der Enumerator instanziiert wurde."
Irgendwelche Vorschläge? Vielen Dank !!!
Code ist wie folgt:
%Vor%Ändern Sie Ihre foreach zu:
%Vor%Bearbeiten:
Wenn die Sicherung fehlschlägt, gehen Sie wie folgt vor:
%Vor%Bearbeiten:
John K erwähnt die Thread-Sicherheit, was ein berechtigtes Problem darstellt, wenn mehrere Threads auf dieselbe Queue
zugreifen. Siehe Ссылка für eine ThreadSafeQueue
-Klasse, die einfache Thread-Sicherheitsprobleme behandelt.
Edit: Hier ist das Threadsicherheitsbeispiel, auf das ich alle hinweise: -)
Hier finden Sie ein Beispiel für die erwähnten Thread-Sicherheitsprobleme. Wie gezeigt, kann die Vorgabe Queue
Elemente "vermissen", während die Anzahl immer noch verringert wird.
Aktualisiert: Um das Problem besser darzustellen. Ich füge nie ein Nullelement zu Queue
hinzu, aber das Standard Queue.Dequeue()
gibt mehrere Nullwerte zurück. Dies allein wäre in Ordnung, aber dabei wird ein gültiger Eintrag aus der internen Sammlung entfernt und der Count
verringert sich. Es ist eine sichere Annahme, dass in diesem speziellen Beispiel jedes null
-Element, das von einer Operation Queue.Dequeue()
zurückgegeben wird, ein gültiges Element darstellt, das nie verarbeitet wurde.
foreach als eine sinnvolle Möglichkeit, die Warteschlange zu durchlaufen, wenn Sie keine Elemente entfernen
Wenn Sie Objekte entfernen und verarbeiten möchten, entfernen Sie sie einfach und sicher eins nach dem anderen und verarbeiten sie, nachdem sie entfernt wurden.
Ein Weg ist das
%Vor%Es ist möglich, dass sich die Anzahl der Elemente in der Warteschlange zwischen "queueList.Count" ändert und queueList.Dequeue (), um threadsicher zu sein, müssen Sie nur Dequeue verwenden, aber Dequeue wird geworfen, wenn die Queue leer ist, also müssen Sie einen Exception-Handler verwenden.
%Vor%Tags und Links c#