web-dev-qa-db-fra.com

Thread.Start () et ThreadPool.QueueUserWorkItem ()

La bibliothèque de classes de base Microsoft .NET fournit plusieurs méthodes pour créer un thread et le démarrer. En gros, l’appel est très similaire à un autre fournissant le même type de service: créer un objet représentant un flux d’exécution (ou plus), lui attribuer un délégué représentant le flux d’exécution à exécuter et, éventuellement, en fonction de la signature du délégué, un objet. en paramètre.

Eh bien, il y a deux approches (essentiellement):

1) Utilisation de la classe System.Threading.Thread.

Thread curr = new Thread(myfunction); /* In a class, myfunction is a void taking an object */
curr.Start(new Object()); /* Or something else to be downcast */

2) Utilisation de la classe System.Threading.ThreadPool.

ThreadPool.QueueUserWorkItem(myfunction, new Object()); /* Same philosophy here */

Existe-t-il des raisons particulières pour lesquelles je devrais utiliser 1) ou 2)? 

  • Des raisons de performance?
  • Des motifs?
  • Quelle est la meilleure approche?

J'ai l'impression que la réponse est: "Dépend de la situation". Pourriez-vous énumérer des situations dans lesquelles une approche est meilleure qu'une autre?

41
Andry

Démarrer un nouveau thread peut être une opération très coûteuse. Le pool de threads réutilise les threads et en amortit ainsi le coût. À moins que vous n'ayez besoin d'un thread dédié, le pool de threads est la solution recommandée. En utilisant un thread dédié, vous avez plus de contrôle sur les attributs spécifiques aux threads tels que la priorité, la culture, etc. En outre, vous ne devriez pas effectuer de tâches de longue durée sur le pool de threads car cela obligerait le pool à générer des threads supplémentaires. 

En plus des options que vous mentionnez, .NET 4 offre d'excellentes abstractions pour la concurrence. Consultez les classes Task et Parallel ainsi que toutes les nouvelles méthodes PLINQ. 

46
Brian Rasmussen

Le pool de threads géré a de très bonnes directives sur le moment où il ne faut PAS utiliser le pool de threads. 

D'après mon expérience, vous souhaitez créer votre propre thread lorsque vous avez besoin d'un thread persistant, dédié et de longue durée. Pour tout le reste, utilisez des délégués asynchrones ou quelque chose comme QueueUserWorkItem, BackgroundWorker ou les fonctionnalités de .NET 4.0 relatives aux tâches.

12
Jim Mischel

Les threads dans ThreadPool sont des threads d'arrière-plan; Tous les threads créés et lancés par un nouvel objet Thread sont des threads de premier plan. 

Un thread d'arrière-plan ne maintient pas l'environnement d'exécution géré en cours d'exécution.

reportez-vous à http://msdn.Microsoft.com/en-us/library/h339syd0.aspx pour plus d'informations.

7
Steel

Dans .NET 4.5.2, ils ont ajouté une nouvelle méthode: HostingEnvironment.QueueBackgroundWorkItem .

Cela semble être une alternative à ThreadPool.QueueUserWorkItem. Les deux se comportent de la même manière, mais l’utilisation de la nouvelle méthode présente des avantages intéressants pour ASP.NET:

La méthode HostingEnvironment.QueueBackgroundWorkItem vous permet planifiez de petits éléments de travail d'arrière-plan. ASP.NET suit ces éléments et empêche IIS de terminer brusquement le processus de travail jusqu'à ce que tout les éléments de travail de base sont terminés. Cette méthode ne peut pas être appelée en dehors d'un domaine d'application géré ASP.NET.

6
dana

En utilisant ThreadPool, vous avez moins de contrôle sur le système de threading. Ceci est un compromis pour simplifier le processus pour vous. Si vous avez tout ce dont vous avez besoin du ThreadPool, vous devriez l’utiliser librement. Si vous avez besoin de plus de contrôle sur les threads, vous devez bien sûr utiliser les classes Thread.

2
Bueller

ThreadPool.QueueUserWorkItem () est essentiellement destiné aux scénarios de type feu et oublie, lorsque l'application ne dépend pas du fait que les opérations se terminent ou non.

Utilisez des fils classiques pour un contrôle plus fin.

1
Tomas Voracek

Vous devez utiliser ThreadPool.QueueUserWorkItem sauf dans les cas suivants:

  • Vous avez besoin d'un fil de premier plan.

  • Vous avez besoin d'un thread pour avoir une priorité particulière.

  • Vous avez des tâches qui bloquent le thread pendant de longues périodes de temps Le pool de threads a un nombre maximal de threads. Par conséquent, un nombre élevé De threads de pool de threads bloqués peut empêcher les tâches de démarrer

  • Vous devez placer des threads dans un appartement mono-threadé. Tous les threads ThreadPool sont dans l'appartement multithread.

  • Vous devez avoir une identité stable associée au thread, ou dédier un thread à une tâche.

Référence link .

0
sotn