2008-09-02 8 views
3

Ich suche nach einer Möglichkeit, eine gleichzeitige Sammlung in C# oder zumindest eine Sammlung, die eine gleichzeitige Enumerator unterstützt. Im Moment erhalte ich eine InvalidOperationException, wenn sich die Sammlung, über die ich iteriere, ändert. Ich konnte die Sammlung nur tief kopieren und mit einer privaten Kopie arbeiten, aber ich frage mich, ob es vielleicht ein besserer WegConcurrent Sammlungen in C#

-Code-Schnipsel:

foreach (String s in (List<String>)callingForm.Invoke(callingForm.delegateGetKillStrings)) 
    { 
     //do some jazz 
    } 

--edit--

Ich habe Die Antwort fand aber auch heraus, dass ich sicherstellen musste, dass der Code, der in die Sammlung geschrieben wurde, auch versuchte, eine Sperre zu erhalten.

private void addKillString(String s) 
    { 
     lock (killStrings) 
     { 
      killStrings.Add(s); 
     } 
    } 

Antwort

5

Andere als ein tun Tief kopieren Sie Ihre beste Wette, die Sammlung sperren könnte sein:

List<string> theList = (List<String>)callingForm.Invoke(callingForm.delegateGetKillStrings); 
    lock(theList.SyncRoot) { 
     foreach(string s in theList) { 
       // Do some Jazz 
     } 
    } 
4

Also ich bin nicht ganz sicher, was Sie fragen, aber die Parallel Extensions Team hat Stellen Sie einige Sachen zusammen, die zur Rechnung passen könnten. Sehen Sie sich insbesondere diesen Blogbeitrag an, etwa enumerating parallel collections. Es enthält auch einen Link zum Herunterladen der parallelen CTP, und Sie können natürlich durch den Rest der Blog-Beiträge durchsuchen, um eine Vorstellung davon zu bekommen, was das CTP tun soll und wie das Programmiermodell funktioniert.

1

Wenn Sie die FCL-Sammlungen verwenden möchten, ist Sperren die einzige Möglichkeit, die Iteration/Änderung von mehreren Threads zu unterstützen, die sich überschneiden können.

Seien Sie vorsichtig, was Sie als Ihr Sperrobjekt verwenden. Die Verwendung von SyncRoot ist nur dann sinnvoll, wenn die Sammlung selbst ein privates Mitglied der Klasse ist, die sie verwendet. Wenn die Sammlung geschützt oder öffentlich ist, kann ein Client Ihrer Klasse eine eigene Sperre für Ihr SyncRoot einrichten, die möglicherweise mit Code in Ihrer Klasse blockiert.

Wenn Sie Interesse an einer Sammlung Sammlung von Drittanbietern haben, empfehle ich die ausgezeichnete C5 Generic Collection Library. Sie haben eine Familie von Baum-basierten Sammlungen, die leicht und sicher ohne Locking verändert und iteriert werden können - Details finden Sie in den Abschnitten 8.10 und 9.11 ihrer (ausgezeichneten) Dokumentation.