2010-08-23 5 views
3

Je souhaite surveiller un fil d'un autre fil. En ce moment, je regarde la propriété threasd.isalive. S'il existe une exception dans le thread, la propriété thread.isalive est toujours true.Surveillance du fil .net

Je veux tuer fil s'il y a une exception en fil ou si le fil est en boucle infinie ..

Would appreacite pour vos entrées/solutions/suggestions.

Raju

Répondre

2

Il semble que le fil est surveillé l'exception qu'il capture est de jeter, sinon, il mettrait fin et sans doute prendre toute votre processus vers le bas aussi bien. Vous pouvez vous abonner à l'événement AppDomain.FirstChanceException pour savoir quand une exception est initialement lancée, mais même si cela se produit, vous ne voulez pas nécessairement tuer le thread (et si le thread attrape l'exception, le gère et continue normalement?) . Au lieu de cela, pensez à laisser l'exception terminer le thread "normalement", puis l'attraper dans votre code moniteur pour l'empêcher d'arrêter le processus.

Il n'y a aucun moyen de savoir si un thread est dans une boucle infinie, mais vous pouvez tuer un thread qui est en cours d'exécution depuis trop longtemps (voir l'exemple de code ci-dessous). Cependant, mettre fin à un thread avec Thread.Abort peut entraîner des problèmes et une odeur de code (voir here). Vous devriez envisager de modifier le thread de travail pour gérer sa propre durée de vie.

class Program 
{ 
    static void Main(string[] args) 
    { 
     if (RunWithTimeout(LongRunningOperation, TimeSpan.FromMilliseconds(3000))) 
     { 
      Console.WriteLine("Worker thread finished."); 
     } 
     else 
     { 
      Console.WriteLine("Worker thread was aborted."); 
     } 
    } 

    static bool RunWithTimeout(ThreadStart threadStart, TimeSpan timeout) 
    { 
     Thread workerThread = new Thread(threadStart); 

     workerThread.Start(); 

     bool finished = workerThread.Join(timeout); 
     if (!finished) 
      workerThread.Abort(); 

     return finished; 
    } 

    static void LongRunningOperation() 
    { 
     Thread.Sleep(5000); 
    } 
} 
3

Habituellement, ceci est un signe de sur-conception. La grande majorité des programmes n'en ont tout simplement pas besoin.

Si vous vraiment besoin de détecter des boucles infinies dans des threads, alors vous devriez structurer la logique de fil pour être dans une boucle principale et l'ont « checkin » à un chien de garde . La boucle principale est bien sûr infinie (sauf si l'on s'attend à ce que le thread "finisse"), mais cela attirera toutes les boucles infinies imbriquées dans la boucle principale.

Le problème est: qu'est-ce que ce "chien de garde"?

Il ne peut pas s'agir d'un autre thread dans le même AppDomain. Il est complètement inapproprié de Thread.Abort un thread dans ce scénario.

Il peut s'agir d'un thread dans un AppDomain distinct. Personnellement, je ne suis pas entièrement satisfait du type de nettoyage "meilleur effort mais non garanti" qui se produit pendant le recyclage d'AppDomain, donc j'évite simplement plusieurs AppDomains.

Cela pourrait être un processus. Cette solution est assez courante dans les solutions d'automatisation très importantes.

Il pourrait également s'agir d'un autre ordinateur. Cette solution est utilisée dans solutions d'automatisation critiques. Une grande partie du travail que j'avais l'habitude de faire impliquait des processus de surveillance sur chaque ordinateur combinés avec des ordinateurs de surveillance fournissant une sorte de cluster de basculement de sauvegarde à chaud.

Je peux honnêtement dire, cependant, que 98% du temps cette question est posée, la réponse est "assurez-vous juste de ne pas mettre une boucle infinie dans le fil en premier lieu." En d'autres termes, le coût énorme de la conception et de la mise en œuvre d'une solution de surveillance ne fait tout simplement pas partie des exigences réelles. Les revues de conception et de code combinées à une bonne stratégie de test sont généralement la meilleure solution.