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 bibliothèque parallèle de tâches et PLINQ.

Classes de collection simultanées

Les classes de collection de l’espace System.Collections.Concurrent de noms fournissent des opérations d’ajout et de suppression thread-safe qui évitent les verrous dans la mesure du possible et utilisent un verrouillage précis 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 fonctionnalités de blocage et de délimitation pour les collections thread-safe qui implémentent System.Collections.Concurrent.IProducerConsumerCollection<T>. Les threads de producteur bloquent si aucun emplacement n’est disponible ou si la collection est pleine. Les threads de consommateur 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 une classe de base ou un magasin de stockage pour fournir des blocages et des limites pour n’importe quelle classe de collection qui prend en charge IEnumerable<T>.
System.Collections.Concurrent.ConcurrentBag<T> Implémentation de conteneur thread-safe qui fournit des opérations d’ajout et d’obtention é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 dans l’espace System.Threading de noms permettent une concurrence affinée et des performances plus rapides en évitant les mécanismes de verrouillage coûteux trouvés dans le code multithreading 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 rendez-vous facile. 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 d’exclusion mutuelle qui provoque le thread qui tente d’acquérir le verrou pour attendre dans une boucle, ou tourner, pendant une période de temps avant de générer 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 différées

Avec l’initialisation différée, la mémoire d’un objet n’est pas allouée tant qu’il n’est pas 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 différés :

Catégorie Descriptif
System.Lazy<T> Fournit une initialisation légère et thread-safe paresseux.
System.Threading.ThreadLocal<T> Fournit une valeur initialisée par thread, chaque thread appelant de manière différée la fonction d’initialisation.
System.Threading.LazyInitializer Fournit des méthodes statiques qui évitent la nécessité d’allouer une instance d’initialisation différée dédiée. 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.

Agréger des exceptions

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 System.Threading.Tasks.Task types et System.Threading.Tasks.Parallel les types et 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