D'autres réponses semblent laisser de côté le point le plus important:
À moins que vous n'essayiez de paralléliser une opération gourmande en ressources processeur afin de la faire plus rapidement sur un site à faible charge, il est inutile d'utiliser un thread de travail.
Cela vaut pour les threads gratuits, créés par new Thread(...)
, et les threads de travail dans le ThreadPool
qui répondent aux QueueUserWorkItem
demandes.
Oui, c'est vrai, vous pouvez affamer le ThreadPool
dans un processus ASP.NET en mettant trop d'éléments de travail en file d'attente. Cela empêchera ASP.NET de traiter d'autres demandes. Les informations contenues dans l'article sont exactes à cet égard; le même pool de threads utilisé pour QueueUserWorkItem
est également utilisé pour traiter les demandes.
Mais si vous mettez en file d'attente suffisamment d'éléments de travail pour provoquer cette famine, vous devriez alors affamer le pool de threads! Si vous exécutez littéralement des centaines d'opérations gourmandes en ressources processeur en même temps, à quoi cela sert-il d'avoir un autre thread de travail pour traiter une requête ASP.NET, alors que la machine est déjà surchargée? Si vous rencontrez cette situation, vous devez complètement repenser!
La plupart du temps, je vois ou j'entends parler de code multi-thread utilisé de manière inappropriée dans ASP.NET, ce n'est pas pour mettre en file d'attente un travail intensif en CPU. C'est pour mettre en file d'attente le travail lié aux E / S. Et si vous souhaitez effectuer des travaux d'E / S, vous devez utiliser un thread d'E / S (port d'achèvement d'E / S).
Plus précisément, vous devez utiliser les rappels asynchrones pris en charge par la classe de bibliothèque que vous utilisez. Ces méthodes sont toujours très clairement étiquetées; ils commencent par les mots Begin
et End
. Comme dans Stream.BeginRead
, Socket.BeginConnect
, WebRequest.BeginGetResponse
et ainsi de suite.
Ces méthodes font utiliser ThreadPool
, mais ils utilisent IOCPs, qui ne pas interférer avec les demandes ASP.NET. Il s'agit d'un type spécial de thread léger qui peut être "réveillé" par un signal d'interruption du système d'E / S. Et dans une application ASP.NET, vous avez normalement un thread d'E / S pour chaque thread de travail, de sorte que chaque demande peut avoir une opération asynchrone en file d'attente. C'est littéralement des centaines d'opérations asynchrones sans aucune dégradation significative des performances (en supposant que le sous-système d'E / S puisse suivre). C'est bien plus que vous n'en aurez jamais besoin.
Gardez simplement à l'esprit que les délégués asynchrones ne fonctionnent pas de cette façon - ils finiront par utiliser un thread de travail, tout comme ThreadPool.QueueUserWorkItem
. Ce ne sont que les méthodes asynchrones intégrées des classes de la bibliothèque .NET Framework qui sont capables de le faire. Vous pouvez le faire vous-même, mais c'est compliqué et un peu dangereux et probablement au-delà de la portée de cette discussion.
La meilleure réponse à cette question, à mon avis, est de ne pas utiliser le ThreadPool
ou une Thread
instance d' arrière-plan dans ASP.NET . Ce n'est pas du tout comme faire tourner un fil dans une application Windows Forms, où vous le faites pour garder l'interface utilisateur réactive et ne vous souciez pas de son efficacité. Dans ASP.NET, votre préoccupation est le débit , et tout ce changement de contexte sur tous ces threads de travail va absolument tuer votre débit, que vous utilisiez ThreadPool
ou non.
S'il vous plaît, si vous vous trouvez en train d'écrire du code de thread dans ASP.NET - demandez-vous s'il pourrait ou non être réécrit pour utiliser des méthodes asynchrones préexistantes, et si ce n'est pas le cas, veuillez déterminer si vous avez vraiment, vraiment besoin du code. pour exécuter dans un fil d'arrière-plan du tout. Dans la majorité des cas, vous ajouterez probablement de la complexité sans aucun avantage net.