2010-04-28 2 views
1

Je cherche à AtomicEnumerable Skeet mais je ne suis pas sûr de savoir comment l'intégrer dans mon exmaple actuelle IEnumerable ci-dessous (http://msmvps.com/blogs/jon_skeet/archive/2009/10/23/iterating-atomically.aspx)Comment refactoriser cet IEnumerable <T> pour qu'il soit compatible avec les threads?

Fondamentalement, je veux foreach mes blahs tapent de manière thread-safe.

grâce

so .. foreach sur plusieurs threads ... donnant l'ordre correct

Blahs b = new blahs();

foreach (string s en b) {}

public sealed class Blahs : IEnumerable<string> 
{ 
    private readonly IList<string> _data = new List<string>() { "blah1", "blah2", "blah3" }; 

    public IEnumerator<string> GetEnumerator() 
    { 
     return _data.GetEnumerator(); 
    } 

    IEnumerator IEnumerable.GetEnumerator() 
    { 
     return GetEnumerator(); 
    } 
} 

Répondre

3

Voulez-vous dire que vous voulez que chaque fil pour voir la séquence même, ou entre tous les fils de discussion, chaque élément doit être vu exactement une fois ?

Pouvez-vous utiliser .NET 4? Dans ce cas, les extensions parallèles (par exemple Parallel.ForEach) est votre ami - il est susceptible d'être beaucoup plus sûr que tout ce que je pouvais trouver :)

EDIT: Si vous voulez simplement itérer sur la liste complètement dans chaque fil, et rien ne va modifier la liste, il sera déjà thread-safe. Si vous devez besoin de modifier la liste, alors vous devriez créer une copie de la liste et itérer sur celle-ci à la place.

+0

J'ai besoin de chaque thread pour voir la même séquence. Malheureusement je suis coincé sur 3.5 pour le moment – DayOne

+0

@DayOne: Voir mon edit. –

1

Si vous avez juste besoin de chaque thread pour voir la même séquence, alors votre code peut être être thread-safe tel quel.

Votre liste _data est privée, elle ne peut donc être modifiée qu'à partir de la classe Blahs elle-même (en supposant que vous ne l'exposez pas ailleurs). La classe List<T> est sûre pour plusieurs lecteurs simultanés, ce qui signifie que tout ce que vous devez faire est de vous assurer que votre classe Blahs ne modifie pas la collection pendant son énumération.

Votre exemple de code est thread-safe tel quel, mais je suis sûr que votre vrai code n'est pas aussi simple.

1

Le code lié résout un problème différent, vous essayez de faire quelque chose de beaucoup plus difficile. Vous ne devez rien faire de spécial avec les itérateurs, tant que la collection n'est pas modifiée pendant son itération. Garantir cela peut être difficile, vous devrez garder un verrou qui empêche tout fil d'ajouter des éléments. Pas génial pour la concurrence.

Si ce n'est pas approprié, vous devrez faire une copie de la collection pour fournir la garantie. Pas de lit de roses non plus, un fil va désormais par définition toujours voir une version périmée de la collection.

Questions connexes