2010-09-22 13 views
4

J'ai besoin de créer plusieurs threads de traitement dans une nouvelle application. Chaque fil a la possibilité d'être "long". Quelqu'un peut-il commenter la viabilité du pool de threads .net intégré ou d'un pool de threads personnalisé existant à utiliser dans mon application?Threadpool, ordre d'exécution et opérations de longue durée

Exigences:

fonctionne bien dans un service Windows. (le travail en attente peut être retiré de la file d'attente, les threads en cours d'exécution peuvent être appelés à s'arrêter)

Possibilité de lancer plusieurs threads.

Le travail doit être démarré dans un ordre séquentiel, mais plusieurs threads peuvent être traités en parallèle.

Les fils suspendus peuvent être détectés et détruits.

EDIT:

Commentaires semblent être menant à filetage manuel. Malheureusement, je suis tenu à la version 3.5 du cadre. Threadpool était attrayant car il me permettait de faire la queue et de créer des fils de discussion lorsque les ressources étaient disponibles. Existe-t-il un bon pattern compatible avec le 3.5 (producteur/consommateur peut-être) qui me donnerait cet aspect de threadpool sans réellement utiliser le threadpool?

+1

Un TP qui peut tuer de manière fiable threads sans déstabiliser sérieusement l'application n'existe pas. –

+0

Ajoutez également une balise multithreading. –

Répondre

6

Vos exigences excluent essentiellement l'utilisation du .NET ThreadPool;

En général, il ne doit pas être utilisé pour des filetages de longue durée, en raison du risque d'épuisement de la piscine. Cependant, il fonctionne bien dans les services Windows, et vous pouvez générer plusieurs threads - limités automatiquement par les limites du pool.

Vous ne pouvez pas garantir les temps de démarrage des threads avec le pool de threads; il peut mettre en file d'attente des threads à exécuter lorsqu'il en a suffisamment, et il ne garantit même pas qu'ils seront démarrés dans la séquence que vous leur soumettez.

Il n'y a pas des moyens faciles à détecter et tuer des fils en cours d'exécution dans le ThreadPool

Donc, essentiellement, vous voulez regarder en dehors de la ThreadPool; Je pourrais recommander que peut-être vous pourriez avoir besoin des instances System.Threading.Thread complètes en raison de toutes vos exigences. Tant que vous gérez les problèmes de concurrence (comme vous devez le faire avec n'importe quel mécanisme de thread), je ne trouve pas la classe Thread très difficile à gérer moi-même, vraiment.

1

La réponse est simple, mais la classe Task (Fx4) répond à la plupart de vos besoins.

L'annulation est coopérative, c'est-à-dire que votre code de tâche doit vérifier.
Mais la détection de fils bloqués est difficile, c'est une exigence très élevée de toute façon.

Mais je peux aussi lire vos exigences comme pour un JobQueue, où le 'travail' consiste en des tâches similaires. Vous pouvez rouler votre propre système qui consomme cette file d'attente et surveille l'exécution sur quelques threads.

+0

Ajoutez un plug pour le framework Reactive Extensions et cette réponse sera parfaite pour l'exigence .NET Framework 3.5 de l'OP. –

+0

@Brian, probablement une bonne idée mais puisque je ne sais rien sur Rx je vais laisser ça à quelqu'un d'autre. –

+0

Je le ferais, mais votre réponse est déjà parfaite. De plus, je ne veux pas voler votre tonnerre :) Le framework Rx contient le backport pour le TPL incluant la classe 'Task'. C'est pourquoi je pensais que vous pouviez inclure une mention dans votre réponse. J'étais votre +1 en passant. –

1

Je l'ai fait essentiellement la même chose avec .Net 3.5 en créant mon propre chef de fil:

  1. classes ouvrières instancier qui savent combien de temps ils ont été en cours d'exécution.
  2. Créer des threads qui exécutent une méthode de travail et les ajouter à un Queue<Thread>.
  3. Un thread superviseur lit les threads de la file d'attente et les ajoute à un Dictionary<int, Worker> lorsqu'il les lance jusqu'à ce qu'il atteigne le nombre maximal de threads en cours d'exécution. Ajoutez le thread en tant que propriété de l'instance Worker.
  4. Lorsque chaque travail se termine, il invoque une méthode de rappel du superviseur qui renvoie son ManagedThreadId.
  5. Le superviseur supprime le thread du dictionnaire et lance un autre thread en attente.
  6. Sondez le dictionnaire des travailleurs en cours d'exécution pour voir si certains ont expiré, ou mettez des minuteurs dans les travailleurs qui invoquent un rappel s'ils prennent trop de temps.
  7. Signalez un travail de longue durée pour quitter ou abandonner son thread.
  8. Le superviseur invoque callbacks à votre fil conducteur pour informer des progrès, etc.