ThreadPool Classe

Définition

Fournit un pool de threads qui peuvent servir à exécuter des tâches, publier des éléments de travail, traiter des E/S asynchrones, attendre au nom d’autres threads et traiter des minuteries.

public ref class ThreadPool abstract sealed
public ref class ThreadPool sealed
public static class ThreadPool
public sealed class ThreadPool
type ThreadPool = class
Public Class ThreadPool
Public NotInheritable Class ThreadPool
Héritage
ThreadPool

Exemples

Dans l’exemple suivant, le thread d’application principal met en file d’attente une méthode nommée ThreadProc pour s’exécuter sur un thread de pool de threads, se met en veille pendant une seconde, puis se ferme. La ThreadProc méthode affiche simplement un message.

using namespace System;
using namespace System::Threading;

ref class Example
{
public:

   // This thread procedure performs the task.
   static void ThreadProc(Object^ stateInfo)
   {
      
      // No state object was passed to QueueUserWorkItem, so stateInfo is 0.
      Console::WriteLine( "Hello from the thread pool." );
   }
};

int main()
{
   // Queue the task.
   ThreadPool::QueueUserWorkItem(gcnew WaitCallback(Example::ThreadProc));

   Console::WriteLine("Main thread does some work, then sleeps.");
   
   Thread::Sleep(1000);
   Console::WriteLine("Main thread exits.");
   return 0;
}
// The example displays output like the following:
//       Main thread does some work, then sleeps.
//       Hello from the thread pool.
//       Main thread exits.
using System;
using System.Threading;

public class Example 
{
    public static void Main() 
    {
        // Queue the task.
        ThreadPool.QueueUserWorkItem(ThreadProc);
        Console.WriteLine("Main thread does some work, then sleeps.");
        Thread.Sleep(1000);

        Console.WriteLine("Main thread exits.");
    }

    // This thread procedure performs the task.
    static void ThreadProc(Object stateInfo) 
    {
        // No state object was passed to QueueUserWorkItem, so stateInfo is null.
        Console.WriteLine("Hello from the thread pool.");
    }
}
// The example displays output like the following:
//       Main thread does some work, then sleeps.
//       Hello from the thread pool.
//       Main thread exits.
Imports System.Threading

Public Module Example
    Public Sub Main()
        ' Queue the work for execution.
        ThreadPool.QueueUserWorkItem(AddressOf ThreadProc)
        
        Console.WriteLine("Main thread does some work, then sleeps.")

        Thread.Sleep(1000)

        Console.WriteLine("Main thread exits.")
    End Sub

    ' This thread procedure performs the task.
    Sub ThreadProc(stateInfo As Object)
        ' No state object was passed to QueueUserWorkItem, so stateInfo is null.
        Console.WriteLine("Hello from the thread pool.")
    End Sub
End Module
' The example displays output like the following:
'       Main thread does some work, then sleeps.
'       Hello from the thread pool.
'       Main thread exits.

Si vous commentez l’appel à la méthode, le Thread.Sleep thread principal se ferme avant l’exécution de la méthode sur le thread du pool de threads. Le pool de threads utilise des threads d’arrière-plan, qui ne maintiennent pas l’application en cours d’exécution si tous les threads de premier plan se sont terminés. (Il s’agit d’un exemple simple d’une condition de race.)

Remarques

De nombreuses applications créent des threads qui passent beaucoup de temps à l’état de veille, en attendant qu’un événement se produise. D’autres threads peuvent entrer dans un état de veille uniquement pour être réveillés régulièrement pour interroger les informations de modification ou de mise à jour de l’état. Le pool de threads vous permet d’utiliser les threads plus efficacement en fournissant à votre application un pool de threads de travail gérés par le système. Voici des exemples d’opérations qui utilisent des threads de pool de threads :

  • Lorsque vous créez un Task objet ou Task<TResult> pour effectuer une tâche de manière asynchrone, par défaut, la tâche est planifiée pour s’exécuter sur un thread de pool de threads.

  • Les minuteurs asynchrones utilisent le pool de threads. Les threads du pool de threads exécutent des rappels à partir de la System.Threading.Timer classe et déclenchent des événements à partir de la System.Timers.Timer classe.

  • Lorsque vous utilisez des handles d’attente inscrits, un thread système surveille l’état des handles d’attente. Une fois l’opération d’attente terminée, un thread worker du pool de threads exécute la fonction de rappel correspondante.

  • Lorsque vous appelez la QueueUserWorkItem méthode pour mettre en file d’attente une méthode pour l’exécution sur un thread de pool de threads. Pour ce faire, transmettez à la méthode un WaitCallback délégué. Le délégué a la signature

    void WaitCallback(Object state)
    
    Sub WaitCallback(state As Object)
    

    state est un objet qui contient des données à utiliser par le délégué. Les données réelles peuvent être transmises au délégué en appelant la QueueUserWorkItem(WaitCallback, Object) méthode .

Remarque

Les threads du pool de threads managés sont des threads d’arrière-plan. Autrement dit, leurs IsBackground propriétés sont true. Cela signifie qu’un ThreadPool thread ne maintient pas une application en cours d’exécution une fois tous les threads de premier plan arrêtés.

Important

Lorsque le pool de threads réutilise un thread, il n’efface pas les données dans le stockage local du thread ou dans les champs marqués avec l’attribut ThreadStaticAttribute . Par conséquent, lorsqu’une méthode examine le stockage local de thread ou les champs marqués avec l’attribut ThreadStaticAttribute , les valeurs qu’elle trouve peuvent être laissées à partir d’une utilisation antérieure du thread du pool de threads.

Vous pouvez également mettre en file d’attente des éléments de travail qui ne sont pas liés à une opération d’attente vers le pool de threads. Pour demander qu’un élément de travail soit géré par un thread dans le pool de threads, appelez la QueueUserWorkItem méthode . Cette méthode prend comme paramètre une référence à la méthode ou au délégué qui sera appelé par le thread sélectionné dans le pool de threads. Il n’existe aucun moyen d’annuler un élément de travail une fois qu’il a été mis en file d’attente.

Les minuteurs de file d’attente et les opérations d’attente inscrites utilisent également le pool de threads. Leurs fonctions de rappel sont mises en file d’attente vers le pool de threads.

Il existe un pool de threads par processus. À compter du .NET Framework 4, la taille par défaut du pool de threads pour un processus dépend de plusieurs facteurs, comme la taille de l’espace d’adressage virtuel. Un processus peut appeler la méthode GetMaxThreads pour déterminer le nombre de threads. Le nombre de threads dans le pool de threads peut être modifié à l’aide de la SetMaxThreads méthode . Chaque thread utilise la taille de pile par défaut et s’exécute à la priorité par défaut.

Remarque

Le code non managé qui héberge le .NET Framework peut modifier la taille du pool de threads à l’aide de la CorSetMaxThreads fonction, définie dans le fichier mscoree.h.

Le pool de threads fournit de nouveaux threads de travail ou des threads d’achèvement d’E/S à la demande jusqu’à ce qu’il atteigne le maximum pour chaque catégorie. Lorsqu’un maximum est atteint, le pool de threads peut créer des threads supplémentaires dans cette catégorie ou attendre que certaines tâches se terminent. À compter du .NET Framework 4, le pool de threads crée et détruit des threads de travail pour optimiser le débit, qui est défini comme étant le nombre de tâches exécutées par unité de temps. Un nombre trop bas de threads peut ne pas permettre une utilisation optimale des ressources disponibles, tandis qu'un nombre trop élevé de threads peut augmenter les conflits de ressources.

Remarque

Quand la demande est faible, le nombre réel de threads du pool peut être inférieur aux valeurs minimales.

Vous pouvez utiliser la méthode GetMinThreads pour obtenir ces valeurs minimales.

Attention

Vous pouvez utiliser la SetMinThreads méthode pour augmenter le nombre minimal de threads. Toutefois, une augmentation non nécessaire de ces valeurs peut entraîner des problèmes de performances. Si vous démarrez trop de tâches en même temps, celles-ci seront lentes. Dans la plupart des cas, le pool de threads sera plus performant avec son propre algorithme d'allocation de threads.

Propriétés

CompletedWorkItemCount

Obtient le nombre d’éléments de travail qui ont été traités jusqu’à présent.

PendingWorkItemCount

Obtient le nombre d’éléments de travail qui sont actuellement en file d’attente pour être traités.

ThreadCount

Obtient le nombre de threads du pool de threads qui existent actuellement.

Méthodes

BindHandle(IntPtr)
Obsolète.
Obsolète.

Lie un handle de système d'exploitation à ThreadPool.

BindHandle(SafeHandle)

Lie un handle de système d'exploitation à ThreadPool.

GetAvailableThreads(Int32, Int32)

Récupère la différence entre le nombre maximal de threads du pool retourné par la méthode GetMaxThreads(Int32, Int32) et le nombre actuel de threads actifs.

GetMaxThreads(Int32, Int32)

Récupère le nombre de demandes au pool de threads pouvant être simultanément actives. Toutes les demandes excédant ce nombre restent dans la file d'attente jusqu'à ce que des threads du pool soient disponibles.

GetMinThreads(Int32, Int32)

Récupère le nombre minimal de threads que le pool de threads crée à la demande, au fur et à mesure que de nouvelles requêtes sont effectuées, avant de basculer sur un algorithme pour la gestion de la création et de la suppression des threads.

QueueUserWorkItem(WaitCallback)

Place une méthode en file d'attente pour exécution. La méthode s'exécute lorsqu'un thread du pool devient disponible.

QueueUserWorkItem(WaitCallback, Object)

Place une méthode en file d'attente pour exécution et spécifie un objet contenant les données que la méthode doit utiliser. La méthode s'exécute lorsqu'un thread du pool devient disponible.

QueueUserWorkItem<TState>(Action<TState>, TState, Boolean)

Place en file d'attente une méthode spécifiée par un délégué Action<T> pour exécution et fournit les données que la méthode doit utiliser. La méthode s'exécute lorsqu'un thread du pool devient disponible.

RegisterWaitForSingleObject(WaitHandle, WaitOrTimerCallback, Object, Int32, Boolean)

Inscrit un délégué pour attendre un WaitHandle, en utilisant, pour indiquer le délai en millisecondes, un entier 32 bits signé.

RegisterWaitForSingleObject(WaitHandle, WaitOrTimerCallback, Object, Int64, Boolean)

Inscrit un délégué pour attendre un WaitHandle, en utilisant, pour indiquer le délai en millisecondes, un entier 64 bits signé.

RegisterWaitForSingleObject(WaitHandle, WaitOrTimerCallback, Object, TimeSpan, Boolean)

Inscrit un délégué en attente de WaitHandle, en spécifiant une valeur TimeSpan pour indiquer le délai.

RegisterWaitForSingleObject(WaitHandle, WaitOrTimerCallback, Object, UInt32, Boolean)

Inscrit un délégué pour attendre un WaitHandle, en utilisant, pour indiquer le délai en millisecondes, un entier 32 bits non signé.

SetMaxThreads(Int32, Int32)

Définit le nombre de demandes au pool de threads pouvant être simultanément actives. Toutes les demandes excédant ce nombre restent dans la file d'attente jusqu'à ce que des threads du pool soient disponibles.

SetMinThreads(Int32, Int32)

Définit le nombre minimal de threads que le pool de threads crée à la demande, au fur et à mesure que de nouvelles requêtes sont effectuées, avant de basculer sur un algorithme pour la gestion de la création et de la suppression des threads.

UnsafeQueueNativeOverlapped(NativeOverlapped*)

Met en file d'attente l'exécution d'une opération d'E/S avec chevauchement.

UnsafeQueueUserWorkItem(IThreadPoolWorkItem, Boolean)

Met en file d’attente l’objet élément de travail spécifié dans le pool de threads.

UnsafeQueueUserWorkItem(WaitCallback, Object)

Met le délégué spécifié en file d'attente dans le pool de threads, mais ne propage pas la pile d'appels vers le thread de travail.

UnsafeQueueUserWorkItem<TState>(Action<TState>, TState, Boolean)

Place en file d'attente une méthode spécifiée par un délégué Action<T> pour exécution et spécifie un objet contenant les données que la méthode doit utiliser. La méthode s'exécute lorsqu'un thread du pool devient disponible.

UnsafeRegisterWaitForSingleObject(WaitHandle, WaitOrTimerCallback, Object, Int32, Boolean)

Inscrit un délégué pour attendre un WaitHandle, en utilisant, pour indiquer le délai en millisecondes, un entier signé 32 bits. Cette méthode ne propage pas la pile appelante vers le thread de travail.

UnsafeRegisterWaitForSingleObject(WaitHandle, WaitOrTimerCallback, Object, Int64, Boolean)

Inscrit un délégué pour attendre un WaitHandle, en utilisant, pour indiquer le délai en millisecondes, un entier 64 bits signé. Cette méthode ne propage pas la pile appelante vers le thread de travail.

UnsafeRegisterWaitForSingleObject(WaitHandle, WaitOrTimerCallback, Object, TimeSpan, Boolean)

Inscrit un délégué en attente de WaitHandle, en spécifiant une valeur TimeSpan pour indiquer le délai. Cette méthode ne propage pas la pile appelante vers le thread de travail.

UnsafeRegisterWaitForSingleObject(WaitHandle, WaitOrTimerCallback, Object, UInt32, Boolean)

Inscrit un délégué pour attendre un WaitHandle, en utilisant, pour indiquer le délai en millisecondes, un entier 32 bits non signé. Cette méthode ne propage pas la pile appelante vers le thread de travail.

S’applique à

Cohérence de thread

Ce type est thread-safe.

Voir aussi