2017-08-24 1 views
2

Je le processus suivant dans un seul thread Environnement:équivalent de tableau dans les collections simultanées

int[] ages = { 40, 30, 18, 23, 60, 24 }; 
for (int i = 0; i < ages.Length; i++) 
{ 
    if (ages[i] < 21) ages[i] = 0; 
} 

À titre d'exemple, mais maintenant je veux faire ce processus dans un environnement Discussion multi. Existe-t-il une collection simultanée simulant un tableau dans un environnement multi-thread?

+1

'' ConcurrentBag peut-être – r1verside

+1

pas tout à fait, ConcurrentBag ne vise pas à maintenir l'ordre des index. Mais sachez que ce code peut être parallélisé sans collisions avec un ParallelFor facilement. – Miguel

+1

ConcurrentBag ne permet pas d'accéder à la clé par index, que je souhaite archiver. –

Répondre

2

La solution la plus proche consiste à utiliser ConcurrentDictionary en utilisant l'index comme clé. La fonction de hachage sera vraiment bon dans ce cas:

var dict = new ConcurrentDictionary<int, int>(Enumerable.Range(0, ages.Length).ToDictionary(i => i, i => ages[i])); 
Parallel.For(0, dict.Count, 
    i => 
    { 
     int value; 
     if (dict.TryGetValue(i, out value) && value < 21) 
      dict.TryUpdate(i, value, 0); 
    }); 

Faites attention au fait que cet exemple n'a pas besoin d'utiliser ConcurrentDictionary du tout parce que vous avez pas de dépendance entre chaque itération.

Parallel.For(0, ages.Length, 
    i => 
    { 
     if (ages[i] < 21) ages[i] = 0; 
    }); 

Ce code fonctionnera parfaitement pour votre exemple. La prochaine fois, utilisez quelque chose de plus complexe comme la somme des éléments du tableau.

Espérons que cette aide!

3

Vous pouvez essayer d'utiliser Parallel LINQ (PLINQ) et laisser .Net se matérialisent le résultat final comme un tableau; dans votre cas:

int[] ages = { 40, 30, 18, 23, 60, 24 }; 

ages = ages 
    .AsParallel() 
    .Select(age => age < 21 ? 0 : age) 
    .ToArray(); 

L'avantage de PLINQ est que .Net est resposnsible pour le choix des collections intérieure, verrouillage, etc. Si vous voulez, par exemple, trouver un âge moyen en parallèle vous tous avez à faire est modifier légèrement la requête:

var averageAge = ages 
    .AsParallel() 
    .Average();