2010-10-24 5 views
3

Si je crée un nouveau thread sur une page ASP.NET, la propriété IsThreadPoolThread est true. La première question est, est-ce à partir du pool ASP.NET ou du pool CLR? La deuxième question est, si elle provient du pool ASP.NET, comment créer un thread à partir de CLR et n'utilisez pas le pool ASP.NET? J'ai besoin d'une solution synchrone pour les demandes de longue durée (full story).Comment créer des threads dans les pages ASP.NET à partir du pool de threads CLR au lieu du pool ASP.NET?

Répondre

8

Tout d'abord, il n'y a pas de différence entre le pool de threads ASP.NET et le pool de threads CLR. ASP.NET traite les pages sur le pool de threads CLR, de sorte que vos pages ASP.NET auront toujours IsThreadPoolThread == true.

Je suis curieux de savoir comment vous créez votre fil. Utilisez-vous le constructeur System.Threading.Thread ou utilisez-vous ThreadPool.QueueUserWorkItem? Si vous utilisez ThreadPool.QueueUserWorkItem, les threads que vous obtenez proviennent du pool de threads .net standard.

Enfin, comme j'ai posted before, il est toujours une mauvaise idée d'essayer des tâches de longue durée à partir d'ASP.NET. Ma suggestion générale est d'utiliser un service Windows d'arrière-plan pour traiter ces demandes, car ASP.NET peut terminer votre thread d'arrière-plan à tout moment. Plus de détails ici, si vous devez le faire dans IIS:

+0

La construction manuelle d'un nouveau Thread à partir d'asp.net n'aboutirait pas à ce que IsThreadPoolThread ait la valeur true, n'est-ce pas? Il doit donc appeler QueueUserWorkItem. Corrigez-moi si j'ai tort, s'il-vous plait. – Fantius

+0

Bien, j'affirmais juste pour ma propre santé mentale. –

+0

Je crée de nouveaux threads à partir de 'System.Threading.Thread'. – Xaqron

4

Bien qu'il y ait un point à faire sur la minimisation de l'impact sur les transactions et la restauration de l'imprévu dans les transactions distribuées, dans cet exemple, il n'est vraiment pas nécessaire de réinventer IIS parce que le processus est long. Le tout "IIS peut mourir à tout moment" est IMHO grandement exagéré.

Oui, vous pouvez redémarrer manuellement IIS ou le pool d'applications, mais vous pouvez redémarrer tout autre service effectuant le même travail avec le même effet. En ce qui concerne l'auto-recyclage, IIS utilise des processus de travail qui se chevauchent et ne mettra jamais fin à un thread démarré avec force (sauf si le délai d'expiration est dépassé). Si tel était le cas nous aurions de sérieux problèmes avec n'importe quelle application hébergée (ce qui empêche IIS de tuer un thread de réponse rapide 0.001ms après le démarrage)

Essentiellement, laissez l'IIS faire ce que IIS fait le mieux et n'insistez pas Lors d'une opération de synchronisation, vous perdrez le thread du pool en attendant de bloquer les E/S, ce que je crois que vous essayez d'éviter. Vous avez déjà fait un bon choix en accédant à Asynchronous Handlers (ASHX), utilisez l'implémentation IHttpAsyncHandler pour générer votre thread personnalisé qui sera ensuite bloqué selon vos désirs sans affecter l'application Web et son pool. Une fois que vous avez lancé un thread d'opération asynchrone, le thread asp.net retournera dans son propre pool et sera prêt à commencer à servir une nouvelle requête. Avec une limite par défaut de 100 threads dans un pool et étant donné que votre processus est low-on-cpu-high-on-bandwidth, je doute que vous manquiez de threads de pool avant de manquer d'espace pipe :). Pour plus d'informations sur la façon de construire gestionnaire async vérifier ce lien (son un ancien article mais non valide moins):

Use Threads and Build Asynchronous Handlers in Your Server-Side Web Code

2

Il y a en fait une différence dans les discussions dans ASP .NET: threads travailleurs et IO threads (threads système que je crois que vous déclarez comme thread CLR).

Maintenant, ASP .NET utilise un thread de travail sur chaque requête, sauf si des configurations personnalisées sont utilisées et ces threads de travail sont limités sur votre numéro de CPU; cette configuration peut être définie dans IIS. Lorsque vous démarrez une tâche asynchrone dans ASP.NET en utilisant un délégué, par exemple, vous utilisez un autre thread de travail. Les délégués sont une manière rapide et sale de démarrer quelque chose de manière asynchrone.NET :)

Si vous souhaitez démarrer un nouveau thread qui n'utilise pas de thread de travail, vous devez explicitement démarrer un nouveau thread comme: new Thread() .... etc. Maintenant ceci vient avec la gestion de code d'alot, et ne suit pas le modèle asynchrone basé par événement. Cependant, il existe une façon de démarrer des threads asynchrones en toute sécurité, c'est-à-dire en utilisant les méthodes asynchrones propres à .NET sur les objets. Les choses que vous utiliseriez normalement comme asynchrones pour des commandes SQL, des appels de service web, etc. Toutes ces méthodes ont un BEGIN et une méthode END. En utilisant ces méthodes, vous n'utiliserez jamais un thread de travail, mais un thread d'E/S.

ASP .NET a quelques astuces dans sa manche lorsqu'il s'agit de pages asynchrones. Il y a deux alternatives:

  1. page Asynchronous: qui permet à votre cycle de page soit asyncronous. Cela signifie fondamentalement que la page est demandée asynchrone.
  2. Tâches de pages asynchrones: ce qui vous permet de définir des tâches qui seront lancées de manière asynchrone au démarrage de la page. C'est un peu comme les threads Asynch, juste que ASP .NET fait beaucoup de choses pour vous, et c'est plus restreint. Je n'ai pas tous les détails, mais s'il vous plaît regarder dans les deux options sur MSDN Library.

Voici un article sur ce sujet: asynch programmin

Questions connexes