Note
L’accès à cette page nécessite une autorisation. Vous pouvez essayer de vous connecter ou de changer d’annuaire.
L’accès à cette page nécessite une autorisation. Vous pouvez essayer de changer d’annuaire.
La System.Threading.ThreadPool classe fournit à votre application un pool de threads de travail gérés par le système, ce qui vous permet de vous concentrer sur les tâches d’application plutôt que sur la gestion des threads. Si vous avez des tâches courtes qui nécessitent un traitement en arrière-plan, le pool de threads managés est un moyen simple de tirer parti de plusieurs threads. L’utilisation du pool de threads est considérablement plus facile dans le Framework 4 et les versions ultérieures, car vous pouvez créer des objets Task et Task<TResult> qui effectuent des tâches asynchrones sur les threads du pool.
.NET utilise des threads de pool pour de nombreux scénarios, notamment les opérations de bibliothèque parallèle de tâches (TPL), l’achèvement des E/S asynchrones, les rappels de timer, les opérations d’attente inscrites, les appels de méthodes asynchrones utilisant des délégués et les connexions de sockets System.Net.
Caractéristiques du pool de threads
Les threads de pool sont des threads d’arrière-plan. Chaque thread utilise la taille de pile par défaut, s'exécute avec la priorité par défaut et se trouve dans le multithread cloisonné. Une fois qu’un thread du pool de threads a terminé sa tâche, il est retourné à une file d’attente de threads en attente. À partir de ce moment, il peut être réutilisé. Cette réutilisation permet aux applications d’éviter le coût de la création d’un thread pour chaque tâche.
Il n’existe qu’un seul pool de threads par processus.
Exceptions dans les threads de pool
Les exceptions non gérées dans les threads de pool entraînent la fin du processus. Il y a trois exceptions à cette règle :
- Une System.Threading.ThreadAbortException est levée dans un thread de pool, car Thread.Abort a été appelée.
- Une System.AppDomainUnloadedException est levée dans un thread de pool, car le domaine d’application est en cours de déchargement.
- Le Common Language Runtime ou un processus hôte met fin au thread.
Pour plus d’informations, consultez Exceptions dans les threads managés.
Nombre maximal de threads dans un pool
Le nombre d’opérations pouvant être mises en file d’attente vers le pool de threads est limité uniquement par la mémoire disponible. Toutefois, le pool de threads limite le nombre de threads qui peuvent être actifs simultanément dans le processus. Si tous les threads du pool de threads sont occupés, des éléments de travail supplémentaires sont mis en file d’attente jusqu’à ce que des threads soient disponibles pour les exécuter. La taille par défaut du pool de threads pour un processus dépend de plusieurs facteurs, tels que la taille de l’espace d’adressage virtuel. Un processus peut appeler la ThreadPool.GetMaxThreads méthode pour déterminer le nombre de threads.
Vous pouvez contrôler le nombre maximal de threads à l’aide des méthodes ThreadPool.GetMaxThreads et ThreadPool.SetMaxThreads.
Remarque
Le code qui héberge le Common Language Runtime peut définir la taille à l’aide de la ICorThreadpool::CorSetMaxThreads méthode.
Valeurs minimales d’un pool de threads
Le pool de threads fournit, à la demande, de nouveaux threads de travail ou des threads d’achèvement d’E/S, jusqu’à ce qu’il atteigne un minimum spécifié pour chaque catégorie. Vous pouvez utiliser la ThreadPool.GetMinThreads méthode pour obtenir ces valeurs minimales.
Remarque
Quand la demande est faible, le nombre réel de threads du pool peut être inférieur aux valeurs minimales.
Lorsqu’un minimum est atteint, le pool de threads peut créer des threads supplémentaires ou attendre que certaines tâches se terminent. Le pool de threads crée et détruit des threads de travail pour optimiser le débit, qui est défini comme le nombre de tâches exécutées par unité de temps. Trop peu de threads peuvent ne pas utiliser de manière optimale les ressources disponibles, tandis que trop de threads peuvent augmenter la contention des ressources.
Avertissement
Vous pouvez utiliser la ThreadPool.SetMinThreads méthode pour augmenter le nombre minimal de threads inactifs. Toutefois, l’augmentation inutile de ces valeurs peut entraîner des problèmes de performances. Si un trop grand nombre de tâches commencent en même temps, toutes ces tâches peuvent sembler lentes. Dans la plupart des cas, le pool de threads fonctionnera mieux grâce à son propre algorithme d'allocation de threads.
Utilisation du pool de threads
Le moyen le plus simple d’utiliser le pool de threads consiste à utiliser la bibliothèque parallèle de tâches (TPL) . Par défaut, les types TPL comme Task et Task<TResult> utilisent des threads du pool de threads pour exécuter des tâches.
Vous pouvez également utiliser le pool de threads en appelant ThreadPool.QueueUserWorkItem à partir du code managé (ou ICorThreadpool::CorQueueUserWorkItem du code non managé) et en transmettant un System.Threading.WaitCallback délégué représentant la méthode qui effectue la tâche.
Une autre façon d’utiliser le pool de threads consiste à mettre en file d’attente des éléments de travail liés à une opération d’attente à l’aide de la méthode ThreadPool.RegisterWaitForSingleObject et à passer un System.Threading.WaitHandle qui, lorsqu’il est signalé ou lorsqu’il a expiré, appelle la méthode représentée par le délégué System.Threading.WaitOrTimerCallback. Les threads de pool sont utilisés pour appeler les méthodes de rappel.
Pour obtenir les exemples, consultez les pages d’API référencées.
Ignorer les vérifications de sécurité
Le pool de threads fournit également les méthodes ThreadPool.UnsafeQueueUserWorkItem et ThreadPool.UnsafeRegisterWaitForSingleObject. Utilisez ces méthodes uniquement lorsque vous êtes certain que la pile de l’appelant n’est pas pertinente pour toutes les vérifications de sécurité effectuées pendant l’exécution de la tâche mise en file d’attente. ThreadPool.QueueUserWorkItem et ThreadPool.RegisterWaitForSingleObject capturent la pile de l’appelant, laquelle est fusionnée dans celle du pool de threads lorsque le thread commence à exécuter une tâche. Si une vérification de sécurité est requise, la pile entière doit être vérifiée. Bien que la vérification assure la sécurité, elle a également un coût de performance.
Quand ne pas utiliser les threads de pool
Il existe plusieurs scénarios dans lesquels il est préférable de créer et de gérer vos propres threads au lieu d’utiliser des threads de pool :
- Vous avez besoin d’un thread de premier plan.
- Vous avez besoin d’un thread pour avoir une priorité particulière.
- Vous avez des tâches qui provoquent le blocage du thread pendant de longues périodes. Le pool de threads a un nombre maximal de threads. Par conséquent, un grand nombre de threads de pool de threads bloqués peuvent empêcher le démarrage des tâches.
- Vous devez placer les threads dans un thread unique cloisonné. Tous les threads ThreadPool se trouvent dans le multithread cloisonné.
- Vous devez disposer d’une identité stable associée au thread ou de dédier un thread à une tâche.