Partager via


Structures de données pour la programmation parallèle

.NET fournit plusieurs types utiles dans la programmation parallèle, notamment un ensemble de classes de collection simultanées, des primitives de synchronisation légères et des types pour l’initialisation différée. Vous pouvez utiliser ces types avec n’importe quel code d’application multithread, y compris la Task Parallel Library (TPL) et PLINQ.

Classes de collections simultanées

Les classes de collection de l’espace de noms System.Collections.Concurrent fournissent des opérations d’ajout et de suppression sécurisées pour les threads qui évitent les verrous dans la mesure du possible et utilisent un verrouillage fin là où les verrous sont nécessaires. Une classe de collection simultanée n’exige pas que le code utilisateur prenne des verrous lorsqu’il accède aux éléments. Les classes de collection simultanées peuvent améliorer considérablement les performances sur les types tels que System.Collections.ArrayList et System.Collections.Generic.List<T> (avec verrouillage implémenté par l’utilisateur) dans les scénarios où plusieurs threads ajoutent et suppriment des éléments d’une collection.

Le tableau suivant répertorie les classes de collection simultanées :

Catégorie Descriptif
System.Collections.Concurrent.BlockingCollection<T> Fournit des fonctions bloquantes et englobantes pour les collections thread-safe qui implémentent System.Collections.Concurrent.IProducerConsumerCollection<T>. Les threads producteurs se bloquent si aucun emplacement n’est disponible ou que la collection est pleine. Les threads consommateurs se bloquent si la collection est vide. Ce type prend également en charge l’accès non bloquant par les consommateurs et les producteurs. BlockingCollection<T> peut être utilisé comme classe de base ou comme magasin de stockage pour assurer le blocage et la liaison des classes de collection qui prennent en charge IEnumerable<T>.
System.Collections.Concurrent.ConcurrentBag<T> Implémentation de conteneur thread-safe qui effectue des opérations Add et Get évolutives.
System.Collections.Concurrent.ConcurrentDictionary<TKey,TValue> Type de dictionnaire simultané et évolutif.
System.Collections.Concurrent.ConcurrentQueue<T> File d’attente FIFO simultanée et évolutive.
System.Collections.Concurrent.ConcurrentStack<T> Pile LIFO simultanée et évolutive.

Pour plus d’informations, consultez Thread-Safe Collections.

Primitives de synchronisation

Les primitives de synchronisation de l’espace de noms System.Threading affinent la concurrence et améliorent les performances en évitant les coûteux mécanismes de verrouillage du code multithread hérité.

Le tableau suivant répertorie les types de synchronisation :

Catégorie Descriptif
System.Threading.Barrier Permet à plusieurs threads de travailler sur un algorithme en parallèle en fournissant un point auquel chaque tâche peut signaler son arrivée, puis bloquer jusqu’à ce que certaines ou toutes les tâches arrivent. Pour plus d’informations, consultez Barrière.
System.Threading.CountdownEvent Simplifie les scénarios de duplication et de jointure en fournissant un mécanisme facile de réunion. Pour plus d’informations, consultez CountdownEvent.
System.Threading.ManualResetEventSlim Primitive de synchronisation similaire à System.Threading.ManualResetEvent. ManualResetEventSlim est plus léger, mais ne peut être utilisé que pour la communication intraprocessus.
System.Threading.SemaphoreSlim Primitive de synchronisation qui limite le nombre de threads pouvant accéder simultanément à une ressource ou à un pool de ressources. Pour plus d’informations, consultez Semaphore et SemaphoreSlim.
System.Threading.SpinLock Primitive de verrou mutex obligeant le thread qui essaie d’acquérir le verrou à attendre dans une boucle ou à rester en attente active pendant un certain temps avant de transmettre son quantum. Dans les scénarios où l’attente du verrou est censée être courte, SpinLock offre de meilleures performances que d’autres formes de verrouillage. Pour plus d’informations, consultez SpinLock.
System.Threading.SpinWait Un petit type léger qui va tourner pendant une heure spécifiée et éventuellement placer le thread dans un état d’attente si le nombre de tours est dépassé. Pour plus d’informations, consultez SpinWait.

Pour plus d’informations, consultez :

Classes d’initialisation tardive

Avec l'initialisation différée (lazy initialization), la mémoire d’un objet n’est pas allouée jusqu’à ce qu’elle soit nécessaire. L’initialisation différée peut améliorer les performances en répartissant uniformément les allocations d’objets au cours de la durée de vie d’un programme. Vous pouvez activer l’initialisation différée pour n’importe quel type personnalisé en encapsulant le type Lazy<T>.

Le tableau suivant répertorie les types d’initialisation paresseux :

Catégorie Descriptif
System.Lazy<T> Assure une initialisation tardive légère et thread-safe.
System.Threading.ThreadLocal<T> Fournit une valeur initialisée tardivement thread par thread, chacun appelant de façon tardive la fonction d’initialisation.
System.Threading.LazyInitializer Fournit des méthodes statiques qui évitent d’avoir à allouer une instance dédiée d’initialisation tardive. Au lieu de cela, ils utilisent des références pour s’assurer que les cibles ont été initialisées à mesure qu’elles sont accessibles.

Pour plus d’informations, consultez Initialisation différée.

Exceptions agrégées

Le System.AggregateException type peut être utilisé pour capturer plusieurs exceptions levées simultanément sur des threads distincts et les renvoyer au thread de jointure en tant qu’exception unique. Les types System.Threading.Tasks.Task et System.Threading.Tasks.Parallel ainsi que PLINQ utilisent AggregateException largement à cet effet. Pour plus d’informations, consultez Gestion des exceptions et Guide pratique pour gérer les exceptions dans une requête PLINQ.

Voir aussi