Thread ou ThreadPool ?
L'asynchronisme est quelque chose de complexe : la bonne technique (Thread, ThreadPool, ...), la synchronisation, la concurrence, etc. Il existe de nombreux ouvrages à ce sujet mais certaines règles très simples peuvent vous faciliter le travail.
La question qui aujourd’hui m’intéresse est : Thread ou ThreadPool ? Voici quelques règles qui pourront, peut être, vous aidez dans ce choix.
On préconise souvent d’utiliser directement un Thread (l’artillerie lourde) :
- Lors de tâches très longues. L’exemple parfait est une boucle “infinie” qui attend les connexion d’un client sur une socket.
- Pour avoir plus de contrôle sur le Thread : attente, destruction, affinité, priorité …
Pour le reste on passera toujours par des ThreadPool (soit 95% des cas) :
- Pour des tâches courtes
- Des opérations d’I/O
D’ailleurs dans le Framework on retrouve très fréquemment le ThreadPool :
- Délégués asynchrones
- BackgroundWorker
- Méthodes Begin* et End*
- La plupart des I/O
Autre point : les performances.
J’ai réalisé un test qui vise à mesurer le temps de création de 1000 tâches. Dans un premier cas cela se traduira par le démarrage de 1000 Thread, et dans second cas l’exécution de 1000 workitems.
// 1er cas : Thread
Thread thread = new Thread(DoWork);
thread.Start();
// 2nd cas : ThreadPool
ThreadPool.QueueUserWorkItem(new WaitCallback((state) =>
{
}));
Les résultats (En release sur un Duo Core 2.2Ghz) sont parlants :
- 230 ms pour le premier cas.
- 0 ms pour le second.
Cela s’explique par le fait que créer un Thread n’est pas anodin : cela consomme beaucoup de ressources et prend du temps.
Le ThreadPool prépare un ensemble de Threads prêt à être utilisés, donc pas de temps de création. De plus, dès qu’un Thread du pool a fini d’exécuter son WorkItem, il sera réutilisé par un autre WorkItem réduisant ainsi la consommation de ressources.
Ce post vous a plu ? Ajoutez le dans vos favoris pour ne pas perdre de temps à le retrouver le jour où vous en aurez besoin :