Les solutions basées sur ConcurrentDictionary<TKey, TValue>
sont généralement bien modulables ; cependant, si vous devez accéder à la base de données des Count
, Keys
ou Values
ou si vous itérez à travers les éléments, cela devient pire qu'une collection à verrouillage unique. C'est parce que ConcurrentDictionary
utilise un groupe de verrous (par défaut, leur nombre dépend du nombre de cœurs du processeur) et l'accès à ces membres entraîne l'acquisition de tous les verrous, de sorte que les performances sont d'autant plus mauvaises que le nombre de cœurs du processeur est élevé.
Une autre réponse suggère d'utiliser des collections immuables. Bien qu'elles soient sûres pour les threads, elles ne sont performantes que si vous y ajoutez rarement de nouveaux éléments (ce qui crée toujours une nouvelle instance, tout en essayant d'hériter du plus grand nombre possible de nœuds de l'instance précédente), mais même dans ce cas, elles sont généralement moins performantes.
Je me suis retrouvé avec une autre solution (que j'ai également appliqué à mon ThreadSafeHashSet<T>
plus tard) : par opposition à ConcurrentDictionary
Je n'utilise qu'un seul verrou, mais seulement temporairement : de temps en temps, les nouveaux éléments sont déplacés vers un espace de stockage totalement dépourvu de verrou, où même le retrait et la réinsertion des mêmes clés se font sans verrou, ce qui les rend très rapides. Aucune temporisation n'est utilisée pour effectuer ces fusions. Une fusion vers la mémoire sans verrou n'a lieu que lorsque la mémoire avec verrou doit être consultée et qu'elle a été créée il y a "suffisamment longtemps", c'est-à-dire configurable .
Remarque : Voir le tableau de comparaison des performances à l'adresse suivante Remarques de la section ThreadSafeDictionary<TKey TValue>
(elle a les mêmes caractéristiques que la classe ThreadSafeHashSet<T>
) pour voir s'il s'agit d'un bon choix pour vos besoins. Aquí vous pouvez trouver la source des tests de performance si vous souhaitez les exécuter vous-même.
La source est disponible aquí et vous pouvez également le télécharger en tant que Paquet NuGet .