2010-06-24 12 views
3

Je crée un fil A et dans ce fil créant un nouveau thread B.Aborting un fil .NET

Alors, comment est la hiérarchie de fil? Le sujet B est fils de Fils A? Ou les threads sont créés en tant que pairs?

Je souhaite annuler le thread parent A qui à son tour tue/abandonne ses threads enfants.

Comment est-ce possible en C#?

+0

Vous devez expliquer pourquoi vous souhaitez abandonner les unités d'exécution. – apoorv020

+0

C# n'a pas de threads. Vous voulez dire "fil .NET". –

Répondre

11

Les threads devraient idéalement jamais abandonné. Ce n'est tout simplement pas sûr. Considérez ceci comme un moyen de réprimer un processus déjà malade. Sinon, évitez comme la peste.

La manière la plus correcte de le faire est d'avoir quelque chose que le code peut vérifier périodiquement, et lui-même décider de quitter.

+0

f.e. juste avec une déclaration de retour vide? – Xorty

+0

@Xorty - cela dépend du scénario et de ce qu'il fait, mais peut-être. Peut-être une exception. Peut-être 'break;' –

4

Thread.Abort fera ce que vous voulez, mais il est recommandé de ne pas abandonner fil, mieux choisir est de penser d'une manière pour la finition des fils correctement par Thread synchronization mécanisme

1

threads sont créés en tant que pairs, obtenir une poignée de filetage A puis appelez ThreadA.Abort() pour l'arrêter de force. Il est préférable de vérifier un booléen dans le thread et s'il évalue à false, quittez le thread.

public class MyClass 
{ 
    public static Thread ThreadA; 
    public static Thread ThreadB; 

    private void RunThings() 
    { 
     ThreadA = new Thread(new ThreadStart(ThreadAWork)); 
     ThreadB = new Thread(new ThreadStart(ThreadBWork)); 

     ThreadA.Start(); 
     ThreadB.Start(); 
    } 

    static void ThreadAWork() 
    { 
     // do some stuff 

     // thread A will close now, all work is done. 
    } 


    static void ThreadBWork() 
    { 
     // do some stuff 

     ThreadA.Abort(); // close thread A 

     // thread B will close now, all work is done. 
    } 
} 
6

Un exemple d'arrêter la manière polie fils:

using System; 
using System.Threading; 

namespace Treading 
{ 
    class Program 
    { 
     static void Main(string[] args) 
     { 
      Console.WriteLine("Main program starts"); 
      Thread firstThread = new Thread(A); 
      ThreadStateMessage messageToA = new ThreadStateMessage(){YouShouldStopNow = false}; 
      firstThread.Start(messageToA); 
      Thread.Sleep(50); //Let other threads do their thing for 0.05 seconds 
      Console.WriteLine("Sending stop signal from main program!"); 
      messageToA.YouShouldStopNow = true; 
      firstThread.Join(); 
      Console.WriteLine("Main program ends - press any key to exit"); 
      Console.Read();// 
     } 

     private class ThreadStateMessage 
     { 
      public bool YouShouldStopNow = false; //this assignment is not really needed, since default value is false 
     } 

     public static void A(object param) 
     { 
      ThreadStateMessage myMessage = (ThreadStateMessage)param; 
      Console.WriteLine("Hello from A"); 
      ThreadStateMessage messageToB = new ThreadStateMessage(); 
      Thread secondThread = new Thread(B); 
      secondThread.Start(messageToB); 

      while (!myMessage.YouShouldStopNow) 
      { 
       Thread.Sleep(10); 
       Console.WriteLine("A is still running"); 
      } 

      Console.WriteLine("Sending stop signal from A!"); 
      messageToB.YouShouldStopNow = true; 
      secondThread.Join(); 

      Console.WriteLine("Goodbye from A"); 
     } 

     public static void B(object param) 
     { 
      ThreadStateMessage myMessage = (ThreadStateMessage)param; 
      Console.WriteLine("Hello from B"); 
      while(!myMessage.YouShouldStopNow) 
      { 
       Thread.Sleep(10); 
       Console.WriteLine("B is still running"); 
      } 
      Console.WriteLine("Goodbye from B"); 
     } 
    } 
} 

Utilisation Thread.Abort(); provoque une exception si votre thread est dans un état d'attente quelconque. C'est un peu ennuyeux à gérer, car il y a un certain nombre de façons qu'un thread peut attendre. Comme d'autres l'ont dit, vous devriez généralement éviter de le faire.

+1

Vous devriez déclarer le membre 'YouShouldStopNow' comme' volatile' – Liran

+0

Merci, je ne le savais pas. Je suppose que cela fait surtout la différence pour les boucles très rapides qui doivent être interrompues lors du premier sondage. – LaustN

3

est ici encore une autre façon de signaler poliment un fil à mourir:

Notez que cette façon favorise des états finis automates où l'esclave vérifie périodiquement l'autorisation de vivre, effectue alors une tâche si cela est autorisé. Les tâches ne sont pas interrompues et sont «atomiques». Cela fonctionne très bien avec des boucles simples ou avec des files d'attente de commandes. Cela garantit également que le thread ne tourne pas à 100% en donnant à l'esclave une période de repos, mettez celui-ci à 0 si vous ne voulez pas vous reposer dans votre esclave.