2012-11-27 1 views
3

J'ai actuellement une application qui est essentiellement une enveloppe pour ~ 10 "LongRunning" Task s. Chaque thread doit continuer à fonctionner indéfiniment, mais parfois ils se bloquent ou tombent en panne, et parfois l'application wrapper se ferme spontanément (je n'ai pas encore pu le retrouver). En outre, l'application wrapper ne peut actuellement s'exécuter que pour un utilisateur, et cet utilisateur doit être celui qui redémarre les threads ou relance l'application entière.Conversion de l'application filetée en service

J'ai actuellement un utilitaire de surveillance pour me faire savoir quand les threads cessent de fonctionner afin qu'ils puissent être redémarrés manuellement, mais je voudrais les redémarrer automatiquement à la place. Je voudrais également que le wrapper soit disponible pour tout le monde pour vérifier l'état des threads, et pour que les threads soient exécutés même si le wrapper ne l'est pas. Sur la base de ces objectifs, je pense que je veux séparer les threads dans un service Windows, et convertir le wrapper en quelque chose qui peut simplement se connecter au service pour vérifier son état et le manipuler.

Comment ferais-je cela? Est-ce une architecture raisonnable? Devrais-je transformer chaque thread en un service distinct, ou devrais-je avoir un seul service multi-thread?

Modifier: Toutes les tâches se connectent au même ensemble de fichiers de sortie (via un TextWriter.Synchronized(StreamWriter)), et je voudrais maintenir ce comportement.
Ils partagent tous la même connexion à la base de données, ce qui signifie que je dois tous les accepter pour fermer la connexion en même temps que nécessaire. Cependant, s'ils étaient séparés, ils pourraient chacun utiliser leur propre connexion à la base de données, et je n'aurais pas à m'inquiéter de la synchronisation. Je soupçonne en fait que cette étape est l'un des points d'échec actuels, donc la scission serait une bonne chose.

+0

Les threads interagissent-ils les uns avec les autres? Devraient-ils partager des ressources statiques? – SLaks

+0

@SLaks - Edité pour ajouter les ressources qu'ils partagent. – Bobson

Répondre

0

Je ne pense pas que déplacer les threads à un service Windows supprime tous les problèmes. Le service va toujours planter aléatoirement et les threads seront toujours sortis au hasard. Je suppose que vos tâches de longue durée implémentent une sorte de boucle de travail. Enveloppez le corps de cette boucle dans un try-catch et enregistrez toutes les exceptions. Ne les remettez pas pour que la tâche ne sorte jamais. Examinez les journaux pour trouver les bogues.

+0

Il ne résoudrait aucun des problèmes sous-jacents, non. Cependant, il serait possible de les tuer et de les redémarrer automatiquement, et de séparer l'interface utilisateur de l'encapsuleur de contrôle des travailleurs. – Bobson

+0

Mon point principal est que le passage à un service n'aide pas. Qu'est ce que tu penses de ça? – usr

+0

À moins qu'il y ait un moyen de tuer et de redémarrer automatiquement les threads dans une application à partir d'une autre application, le déplacer vers un service serait utile. Je sais comment tuer et redémarrer un service.Evidemment, il vaudrait mieux * trouver * et corriger les bugs, mais je ne peux jamais garantir que le thread ne s'est pas seulement bloqué en attendant quelque chose (ce qui est un problème récurrent avec notre base de données). La seule façon dont je peux dire * ça * est de voir si le travail est fait. – Bobson

2

Je vous suggère de rester dans un service de multithreading si possible. Assurez-vous simplement que les threads sont gérés correctement lorsque Service Stop est déclenché. Placez des drapeaux de frein à l'intérieur des blocs de code qui prendront beaucoup de temps à s'exécuter. De cette façon, vous rendrez votre service réactif sur l'événement Stop. Consignez toutes les exceptions et assurez-vous d'attendre que tous les threads se terminent jusqu'à ce que le service soit définitivement arrêté. Cela vous empêchera d'exécuter la même "tâche" dans plusieurs threads.

Maintenir un service est finalement plus facile que de multiples services.

Le fractionnement vers plusieurs services serait raisonnable si vous avez besoin de fonctionnalités distinctes qui peuvent fonctionner ou non l'une à côté de l'autre.

+0

Avec ce modèle, comment gérer le scénario de blocage dans lequel je veux redémarrer un thread qui ne répond pas à l'ensemble? – Bobson

+0

Du point de vue du service complet, ce n'est pas possible. Le redémarrage devrait redémarrer tous les threads. Cependant, vous pouvez déclarer chaque thread comme privé dans le thread de service principal et les surveiller. Si vous constatez que le thread spécifique ne répond pas, annulez-le et lancez un nouveau thread ou vous pouvez décider de redémarrer le service complet. –

+0

Malheureusement, en raison d'autres compromis architecturaux, chaque thread dans la même application utilise la même connexion à la base de données, et si cette connexion ne répond pas, il n'y a aucun moyen de vérifier si les threads fonctionnent. D'où l'utilité du moniteur, qui a sa propre connexion. Serait-il possible d'envoyer un message au service pour lui dire "Redémarrer le fil X"? – Bobson

Questions connexes