IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

C# Discussion :

Comment arrêter un Thread proprement


Sujet :

C#

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre régulier
    Profil pro
    Inscrit en
    Novembre 2006
    Messages
    284
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2006
    Messages : 284
    Points : 79
    Points
    79
    Par défaut Comment arrêter un Thread proprement
    Bonjour,
    J'ai une petite question concernant l'arrêt d'un Thread.
    De ce que j'ai vu, il est clairement déconseillé d'utiliser Abort().
    En plus cette méthode lève une exception donc ce n'est pas terrible.

    J'ai vu une technique ou un utilise un booléen.
    Code c# : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
     
    public partial class MainWindow : Window
    {
    	private bool ThreadContinue = false;
    	private Thread ThreadShearch;
     
    	public MainWindow()
    	{
    		InitializeComponent();
    	}
     
    	private void Start_Click(object sender, RoutedEventArgs e)
    	{
    		ThreadContinue = true;
    		ThreadShearch = new Thread(ConsoleWrite) { Name = "ThreadShearch" };
    		ThreadShearch.Start();
    	}
     
    	private void Stop_Click(object sender, RoutedEventArgs e)
    	{
    		ThreadContinue = false;
    	}
     
    	private void ConsoleWrite()
    	{
    		for (int i = 0; i < 30000 && ThreadContinue; i++)
    			Console.WriteLine(i);
    	}
     
    	private void LongRequest()
    	{
    		Thread.Sleep(10000);
    	}
    }

    Dans ce cas ci cela fonctionne très bien car on a la possibilité de vérifier régulièrement la valeur du booléen.
    Hors dans le cas suivant je ne sais pas comment faire.
    Imaginons une requête de recherche un peu spécifique qui prend un certain temps (25s).
    Je voudrais pouvoir l'annuler, hors je n'ai pas de boucle et du coup je ne sais pas vraiment comment faire.
    Avez vous des idées?


    J'ai vu ce lien mais c'est le même problème.
    http://faqcsharp.developpez.com/?pag...fx_thread_stop

  2. #2
    Expert confirmé

    Homme Profil pro
    Développeur .NET
    Inscrit en
    Novembre 2010
    Messages
    2 066
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur .NET

    Informations forums :
    Inscription : Novembre 2010
    Messages : 2 066
    Points : 4 233
    Points
    4 233
    Par défaut
    j'ai utilisé le abort même si c'est déconseillé, ça fait très bien son travail

  3. #3
    Membre actif Avatar de brachior
    Homme Profil pro
    Doctorant
    Inscrit en
    Mai 2011
    Messages
    190
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 37
    Localisation : France, Seine et Marne (Île de France)

    Informations professionnelles :
    Activité : Doctorant
    Secteur : Enseignement

    Informations forums :
    Inscription : Mai 2011
    Messages : 190
    Points : 293
    Points
    293
    Par défaut
    En principe on envoie une exception (ThreadInterruptedException) au thread qui lui le catch et le traite en circonstance (arrêt propre ...)

    PS : une des raison pour laquelle l'arrêt violent d'un thread est "interdit" c'est qu'il se peut que le thread soit en train d'utiliser un objet, et son arrêt brutal peut rendre cet objet inutilisable pour l'ensemble du programme

  4. #4
    Membre régulier
    Profil pro
    Inscrit en
    Novembre 2006
    Messages
    284
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2006
    Messages : 284
    Points : 79
    Points
    79
    Par défaut
    Donc du coup ça serait quelque chose du genre:
    Code c# : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    private void Stop_Click(object sender, RoutedEventArgs e)
    {
         new ThreadInterruptedException();
    }

    Comment un thread en particulier c'est que c'est pour lui et non pour le voisin?

  5. #5
    Membre actif Avatar de brachior
    Homme Profil pro
    Doctorant
    Inscrit en
    Mai 2011
    Messages
    190
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 37
    Localisation : France, Seine et Marne (Île de France)

    Informations professionnelles :
    Activité : Doctorant
    Secteur : Enseignement

    Informations forums :
    Inscription : Mai 2011
    Messages : 190
    Points : 293
    Points
    293
    Par défaut
    Oula non ^^
    Si tu fais cela, c'est le thread qui aura exécuté cette méthode qui recevra l'exception ^^'

    D'après la doc MSDN la méthode Abort fait ceci :
    Citation Envoyé par MSDN
    Raises a System.Threading.ThreadAbortException in the thread on which it is invoked, to begin the process of terminating the thread. Calling this method usually terminates the thread.
    Donc le fait d'appeler Abort sur un Thread, lève l'exception ThreadAbortException qu'il faut catcher pour fermer proprement ...

    Donc dans ton Thread ça doit donner un truc du genre :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
     
    public void start()
    {
      try
      {
        // do something
      }
      catch(ThreadAbortException)
      {
        // exit
      }
    }
    EDIT : Il faut bien évidement pas qu'il y ai un catch de Exception ou de ThreadAbortException dans le try de la méthode ^^

  6. #6
    Expert éminent sénior Avatar de Pol63
    Homme Profil pro
    .NET / SQL SERVER
    Inscrit en
    Avril 2007
    Messages
    14 177
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France, Puy de Dôme (Auvergne)

    Informations professionnelles :
    Activité : .NET / SQL SERVER

    Informations forums :
    Inscription : Avril 2007
    Messages : 14 177
    Points : 25 125
    Points
    25 125
    Par défaut
    je préfère l'interrupt à l'abort

    l'interrupt on ne sait pas trop ce qu'il fait, mais l'abort je sais que c'est parfois pas terrible
    l'abort déclenché une exception qui se propage à travers chaque try catch, souvent l'abort déclenche l'exception dans des dll du framework (qui sont codées en .net rappelons le) et nous avons vu des cas où ca fait un peu peur quand même l'endoit ou c'est tombé

    une des solutions et d'ignorer la fin du thread, et d'en démarrer un autre, mais ca ne peut pas s'appliquer dans tous les cas
    quand c'est x requete de suite sans boucle, on peut tester le booléen après chaque requete, si celles ci sont longues, ignorer le thread peut aller
    par contre pour un traitement couteux de 10 minutes le laisser tourner pour rien n'est pas génial

  7. #7
    Membre averti Avatar de megamario
    Homme Profil pro
    VB6/VB.net/C/C++/C#
    Inscrit en
    Septembre 2008
    Messages
    929
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 53
    Localisation : France, Indre et Loire (Centre)

    Informations professionnelles :
    Activité : VB6/VB.net/C/C++/C#
    Secteur : Industrie

    Informations forums :
    Inscription : Septembre 2008
    Messages : 929
    Points : 312
    Points
    312
    Par défaut
    Bonjour,

    Excusez moi de remonter ce post aussi vieux, mais je suis confronté à ce souci.

    Dans mon soft j’interroge deux dll bloquante et pour ne pas tout bloquer, je démarre leur gestion dans des Threads indépendant. Seulement l'une des 2 mets plus de 30 secondes à répondre (je voie, actuellement, avec le fournisseur de cette dll, pourquoi c'est si long).

    Se sont 2 dll de sécurité d’accès à nos logiciels, dès que l'une d'être elle a répondu positif, je démarre le logiciel. Lorsque tout se passe bien j’arrête les threads proprement grâce à des boucles, mais vu que l'une des dll est très longue, l'utilisateur peut fermer le soft avant que la dll à rendu la main dans son thread de gestion.

    En mode debug, j'attend les 10 ou 20 secondes restant avant d'avoir la main sur l'IDE.

    J'ai essayé abort, mais cela passe dans le catch qu'après que la dll à rendu la main donc cela ne m'arrange pas plus. Y a t'il un moyen de cassé ce genre de dll qui bloque.
    J'ai fait un = Nothing sur le thread mais idem.

    J’espère arrivé à réduire ce temps avec le fournisseur de la dll, car la c'est inacceptable, mais pour mes connaissances perso j'aimerai savoir s'il y a moyen de débloquer l'appel d'une dll.

    Merci

Discussions similaires

  1. Comment arrêter mon Thread ?
    Par avenger22 dans le forum Général Java
    Réponses: 10
    Dernier message: 06/04/2014, 10h27
  2. Réponses: 6
    Dernier message: 28/05/2013, 12h24
  3. Comment arréter un thread qui exécute une instruction bloquante
    Par nibor2luxe dans le forum Concurrence et multi-thread
    Réponses: 15
    Dernier message: 28/02/2008, 17h03
  4. comment arrêter un update proprement
    Par youxx dans le forum Oracle
    Réponses: 2
    Dernier message: 14/05/2007, 16h59
  5. Réponses: 18
    Dernier message: 06/04/2005, 14h09

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo