Je vois beaucoup de gens dans les articles de blog et ici sur SO évitant ou déconseillant l'utilisation de la Thread
classe dans les versions récentes de C # (et je veux dire bien sûr 4.0+, avec l'ajout de Task
& friends). Même avant, il y avait des débats sur le fait que la fonctionnalité d'un ancien thread peut être remplacée dans de nombreux cas par la ThreadPool
classe.
En outre, d'autres mécanismes spécialisés rendent la Thread
classe moins attrayante, comme le Timer
remplacement du combo laid Thread
+ Sleep
, tandis que pour les interfaces graphiques que nous avons BackgroundWorker
, etc.
Pourtant, le Thread
semble rester un concept très familier pour certaines personnes (moi y compris), des personnes qui, confrontées à une tâche qui implique une sorte d'exécution parallèle, se lancent directement dans l'utilisation de la bonne vieille Thread
classe. Je me suis demandé récemment s'il était temps de modifier mes habitudes.
Ma question est donc la suivante: y a-t-il des cas où il est nécessaire ou utile d'utiliser un vieil Thread
objet ordinaire au lieu de l'une des constructions ci-dessus?
la source
64.5k
. Un spectacle assez impressionnantRéponses:
La classe Thread ne peut pas être rendue obsolète car il s'agit évidemment d'un détail d'implémentation de tous les autres modèles que vous mentionnez.
Mais ce n'est pas vraiment votre question; votre question est
Sûr. Dans les cas précis où l'une des constructions de niveau supérieur ne répond pas à vos besoins.
Mon conseil est que si vous vous trouvez dans une situation où les outils d'abstraction supérieure existants ne répondent pas à vos besoins et que vous souhaitez implémenter une solution à l'aide de threads, vous devez identifier l'abstraction manquante dont vous avez vraiment besoin , puis implémenter cette abstraction à l'aide de threads , puis utilisez l'abstraction .
la source
Les threads sont un élément de base pour certaines choses (à savoir le parallélisme et l'asynchronie) et ne doivent donc pas être supprimés. Cependant , pour la plupart des gens et la plupart des cas d'utilisation, il existe des éléments plus appropriés à utiliser que vous avez mentionnés, tels que les pools de threads (qui offrent un bon moyen de gérer de nombreux petits travaux en parallèle sans surcharger la machine en générant 2000 threads à la fois),
BackgroundWorker
( qui encapsule les événements utiles pour un seul travail de courte durée).Mais ce n'est pas parce que dans de nombreux cas, ceux-ci sont plus appropriés qu'ils empêchent le programmeur de réinventer inutilement la roue, de faire des erreurs stupides, etc., cela ne signifie pas que la classe Thread est obsolète. Il est toujours utilisé par les abstractions citées ci-dessus et vous en auriez toujours besoin si vous avez besoin d'un contrôle fin sur les threads qui n'est pas couvert par les classes plus spéciales.
Dans le même ordre d'idées,
.NET
n'interdit pas l'utilisation de tableaux, bienList<T>
qu'ils conviennent mieux à de nombreux cas où les gens utilisent des tableaux. Simplement parce que vous voudrez peut-être encore construire des choses qui ne sont pas couvertes par la bibliothèque standard.la source
Task
etThread
sont des abstractions différentes. Si vous souhaitez modéliser un thread, laThread
classe reste le choix le plus approprié. Par exemple, si vous avez besoin d'interagir avec le fil actuel, je ne vois pas de meilleurs types pour cela.Cependant, comme vous le faites remarquer, .NET a ajouté plusieurs abstractions dédiées qui sont préférables
Thread
dans de nombreux cas.la source
La
Thread
classe n'est pas obsolète, elle est toujours utile dans des circonstances particulières.Là où je travaille, nous avons écrit un `` processeur d'arrière-plan '' dans le cadre d'un système de gestion de contenu: un service Windows qui surveille les répertoires, les adresses e-mail et les flux RSS, et chaque fois que quelque chose de nouveau apparaît, exécutez une tâche dessus - généralement pour importer le Les données.
Les tentatives d'utilisation du pool de threads pour cela n'ont pas fonctionné: il essaie d'exécuter trop de choses en même temps et de détruire les disques, nous avons donc implémenté notre propre système d'interrogation et d'exécution en utilisant directement la
Thread
classe.la source
Les nouvelles options rendent l' utilisation directe et la gestion des threads (coûteux) moins fréquentes.
Ce qui est une manière très coûteuse et relativement complexe de faire des choses en parallèle.
Notez que la dépense compte le plus: vous ne pouvez pas utiliser un thread complet pour faire un petit travail, ce serait contre-productif. Le ThreadPool combat les coûts, la classe Task les complexités (exceptions, attente et annulation).
la source
Pour répondre à la question " Y a-t-il des cas où il est nécessaire ou utile d'utiliser un vieil objet Thread ?" t jamais interagir avec à partir d'un fil différent.
Par exemple, si vous écrivez une application qui s'abonne pour recevoir des messages d'une sorte de file d'attente de messages et que votre application va faire plus que simplement traiter ces messages, il serait utile d'utiliser un thread car le thread sera autonome (c'est-à-dire que vous n'attendez pas que cela soit fait), et ce n'est pas de courte durée. L'utilisation de la classe ThreadPool sert davantage à mettre en file d'attente un tas d'éléments de travail de courte durée et à permettre à la classe ThreadPool de gérer efficacement le traitement de chacun d'entre eux lorsqu'un nouveau Thread est disponible. Les tâches peuvent être utilisées là où vous utiliseriez directement Thread, mais dans le scénario ci-dessus, je ne pense pas qu'elles vous achèteraient beaucoup. Ils vous aident à interagir plus facilement avec le fil (ce que le scénario ci-dessus ne fait pas
la source
System.IO.Threading.Thread
.Probablement pas la réponse que vous attendiez, mais j'utilise Thread tout le temps lors du codage avec .NET Micro Framework. MF est assez réduit et n'inclut pas d'abstractions de plus haut niveau et la classe Thread est super flexible lorsque vous avez besoin d'obtenir le dernier bit de performance d'un processeur à faible MHz.
la source
Vous pouvez comparer la classe Thread à ADO.NET. Ce n'est pas l'outil recommandé pour faire le travail, mais il n'est pas obsolète. D'autres outils s'y ajoutent pour faciliter le travail.
Ce n'est pas faux d'utiliser la classe Thread sur d'autres choses, surtout si ces choses ne fournissent pas une fonctionnalité dont vous avez besoin.
la source
Ce n'est pas définitivement obsolète.
Le problème avec les applications multithreads est qu'elles sont très difficiles à obtenir (le comportement, l'entrée, la sortie et l'état interne souvent indéterministes sont importants), donc un programmeur doit pousser autant de travail que possible vers le framework / les outils. Abstenez-le. Mais l'ennemi mortel de l'abstraction est la performance.
J'irais avec les threads et les verrous uniquement s'il y a de sérieux problèmes de performances, des objectifs de haute performance.
la source
J'ai toujours utilisé la classe Thread lorsque j'ai besoin de compter et de contrôler les threads que j'ai lancés. Je me rends compte que je pourrais utiliser le pool de threads pour contenir tout mon travail exceptionnel, mais je n'ai jamais trouvé de bon moyen de garder une trace de la quantité de travail actuellement en cours ou de son statut.
Au lieu de cela, je crée une collection et y place les fils après les avoir tournés - la toute dernière chose qu'un fil fait est de se retirer de la collection. De cette façon, je peux toujours dire combien de threads sont en cours d'exécution, et je peux utiliser la collection pour demander à chacun ce qu'il fait. S'il y a un cas où je dois tous les tuer, normalement vous devez définir une sorte d'indicateur "Abandonner" dans votre application, attendez que chaque thread remarque qu'il se termine seul - dans mon cas, je peut parcourir la collection et émettre un Thread.Abort à chacun à son tour.
Dans ce cas, je n'ai pas trouvé de meilleur moyen de travailler directement avec la classe Thread. Comme Eric Lippert l'a mentionné, les autres ne sont que des abstractions de niveau supérieur, et il est approprié de travailler avec les classes de niveau inférieur lorsque les implémentations de haut niveau disponibles ne répondent pas à vos besoins. Tout comme vous devez parfois faire des appels d'API Win32 lorsque .NET ne répond pas exactement à vos besoins, il y aura toujours des cas où la classe Thread est le meilleur choix malgré les "avancées" récentes.
la source