2010-09-10 5 views
-1

J'ai un objet qui contient une collection d'éléments. Je souhaite pouvoir ajouter des éléments à la collection via une méthode AddItem et également parcourir tous les éléments de la collection. Mon objet doit être thread safe. J'utilise un ReaderWriterLockSlim pour assurer une synchronisation correcte. Comment synchroniser la méthode GoThroughAllItems? Dois-je commencer un grand ReadLock pendant toute sa durée, qui peut être très longue, ou devrais-je libérer le verrou pour chaque élément récupéré de la collection, et ré-acquérir le verrou pour le prochain?Synchroniser Lire la collection d'écriture dans .NET

Voici quelques exemples de code:

 
private ReaderWriterLockSlim @lock = new ReaderWriterLockSlim(); 
private List items = new List(); 

public void AddItem(Item item) 
{ 
    [email protected](); 

    try 
    { 
     //do something with item and add it to the collection 
     this.items.Add(item); 
    } 
    finally 
    { 
     [email protected](); 
    } 
} 

public void GoThroughAllItems() 
{ 
    [email protected](); 

    try 
    { 
     foreach (Item item in this.Items) 
     { 
#if option2 
      [email protected](); 
#endif 

      //process item, which may take a long time 

#if option2 
      [email protected](); 
#endif 
     } 
    } 

#if option2 
    catch 
#endif 
#if option1 
    finally 
#endif 
    { 
     [email protected](); 
    } 
} 

Répondre

0

La meilleure façon est là pour créer une copie de la collecte, puis itérer dessus. Il a des frais généraux de mémoire importants (mais il sera publié peu de temps après).

Code Pseudo:

read lock 
    foreach oldColl 
     populate newColl 
exit lock 

    foreach newColl 
     do things 

et vous codez avec des serrures par article ne fonctionnera pas, parce que d'autres thread peut modifier la collecte et provoquera une erreur, car foreach ne permet pas de modification des collections.

+0

Merci, mais, en général, je pense que la copie peut être trop chère à considérer. –

+0

@Ricardo Peres cher en termes de quoi? – Andrey

+0

En termes de devoir copier N éléments d'un côté à l'autre, bien sûr. –

0

Je choisirais simplement votre première option avec la région de lecture autour de la foreach puisque plusieurs threads sont autorisés dans le bloc de lecture, peu importe que ce soit plutôt lent. D'autre part, l'opération d'écriture exclusive est assez rapide. Cela devrait donc être une bonne solution.

Questions connexes