Wie kann ich eine Warteschlangensammlung in einer Schleife ändern?

8

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%     
user9969 06.02.2010, 19:42
quelle

3 Antworten

10

Ä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.

%Vor%     
Cory Charlton 17.02.2010, 19:05
quelle
1

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%     
John Knoeller 06.02.2010 19:56
quelle
0

Für mich sieht es so aus, als würden Sie versuchen, das Element in der Warteschlange einzeln zu verarbeiten.

Wie wäre es, dies in while loop zu verpacken und jedes Element von Dequeue zu verarbeiten, bis die Warteschlange leer ist?

    
Gant 06.02.2010 19:46
quelle

Tags und Links