2010-11-29 5 views
15

Ich habe eine einfache Anwendung, die einem HashSet <string> etwa 7 Millionen kurze Strings hinzufügt. Gelegentlich bekomme ich eine Ausnahme während eines Aufrufs von Hashset.Add(): System.Collections.Generic.HashSet`1.IncreaseCapacity(): Index lag außerhalb der Grenzen des Arrays.IndexOutOfRangeException beim Hinzufügen zu Hashset <T>

Es ist ein zeitweiliges Problem und scheint im Zusammenhang mit Speicher, aber das ist auf einem win2k8 R2-Server mit 16 GB, nicht viel anderes los, der größte Teil dieses physikalischen Speichers ist verfügbar. Irgendwelche Ideen?

+5

fügen Sie Multi-Threading hinzu? – herzmeister

+0

Ich habe gerade ein Projekt erstellt, das int.MaxValue Guids auf einem 4-Kern-PC mit Parallelisierung hinzufügt, und es ist nicht fehlgeschlagen. –

+0

Yup, das war das Problem. Ich hätte es wissen müssen. Danke herzmeister – dcrobbins

Antwort

35

Die HashSet<T> ist nicht threadsicher. Insbesondere wenn Elemente in einem Multi-Threaded-Szenario hinzugefügt werden und die interne Kapazität erhöht werden muss, können Dinge nicht mehr synchron sein.

+3

+1 IndexOutOfRangeException ist ein eindeutiger Indikator dafür, dass es Laufzeit Threading-Probleme gibt, wenn es von einem Add-Vorgang für eine Sammlung ausgelöst wird. –

5

Die Instanzmethoden unter HashSet<T> sind nicht Thread-sicher. Insbesondere wenn Sie versuchen, ein Element hinzuzufügen, das dazu führen würde, dass die Menge die Grenzen des vorhandenen Arrays in mehr als einem Thread überschreitet, werden die Instanzvariablen verwendet, um die Größe des Satzes und den letzten Index zu überwachen Das Set kann in beiden Threads aktualisiert werden. Insbesondere, wenn der letzte Indexwert durch den zweiten Thread (mit einem größeren Wert) aktualisiert wird, bevor der erste Thread das Kopieren des Zielarrays beendet hat, könnte er versuchen, auf ein Element des lokalen Arrays zuzugreifen, das aufgrund des lokalen Arrays nicht existiert wurde zugewiesen, um nur halb so viele Elemente wie die vom zweiten Thread zugewiesen zu halten.