I J'ai fait un essai il y a quelque temps (également : sur GitHub ). Ma mise en œuvre a connu quelques problèmes, que je n'aborderai pas ici. Laissez-moi vous dire, plus important encore, ce que j'ai appris.
Tout d'abord, il n'y a aucune chance que vous obteniez une implémentation complète de IList<T>
qui est sans verrou et sans risque pour les fils. En particulier, les insertions et suppressions aléatoires sont pas ne va pas fonctionner, à moins que vous n'oubliiez également l'accès aléatoire O(1) (c'est-à-dire, à moins que vous ne "trichiez" et n'utilisiez qu'une sorte de liste liée et que l'indexation soit nulle).
Ce que je pensée pourrait être utile, c'est un sous-ensemble limité, à l'abri des threads, de IList<T>
en particulier, une qui permettrait à un Add
et fournir des données aléatoires en lecture seule accès par index (mais pas de Insert
, RemoveAt
etc., et pas de hasard non plus écrire accès).
C'était le but de mon ConcurrentList<T>
mise en œuvre . Mais lorsque j'ai testé ses performances dans des scénarios multithreads, j'ai constaté que la simple synchronisation ajoute à un List<T>
était plus rapide . Fondamentalement, l'ajout à un List<T>
est déjà rapide comme l'éclair ; la complexité des étapes de calcul impliquées est minuscule (incrémenter un index et assigner à un élément dans un tableau ; c'est Vraiment. ). Vous auriez besoin d'un tonne d'écritures simultanées pour voir une quelconque forme de conflit de verrouillage ; et même dans ce cas, les performances moyennes de chaque écriture seraient toujours supérieures à celles de l'implémentation plus coûteuse, bien que sans verrouillage, de la solution ConcurrentList<T>
.
Dans le cas relativement rare où le tableau interne de la liste doit se redimensionner, vous payez un petit prix. J'ai donc fini par conclure que c'était la un scénario de niche dans lequel un add-on ConcurrentList<T>
aurait un sens : lorsque vous voulez garanti faible coût d'ajout d'un élément sur chaque appel (donc, par opposition à un objectif de performance amorti).
C'est tout simplement une classe qui n'est pas aussi utile qu'on pourrait le croire.
7 votes
ConcurrentBag<T> ( msdn.microsoft.com/pt-br/library/ )
6 votes
@RodrigoReis, ConcurrentBag<T> est une collection non ordonnée, alors que List<T> est ordonnée.
5 votes
Comment pouvez-vous avoir une collection ordonnée dans un environnement multithread ? Vous n'auriez jamais le contrôle de la séquence des éléments, par conception.
0 votes
Utilisez plutôt un cadenas
0 votes
Il existe un fichier appelé ThreadSafeList.cs dans le code source de Dotnet qui ressemble beaucoup au code ci-dessous. Il utilise également ReaderWriterLockSlim et j'essaie de comprendre pourquoi utiliser cela au lieu d'un simple lock(obj) ?
0 votes
Ok je vois que c'est une amélioration des performances puisque les verrous de lecteur ne se verrouillent pas vraiment à moins qu'il y ait une écriture en cours, utile si vous avez plusieurs threads qui lisent la même liste.