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#

  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 065
    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 065
    Points : 4 229
    Points
    4 229
    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 154
    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 154
    Points : 25 072
    Points
    25 072
    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
    Cours complets, tutos et autres FAQ ici : C# - VB.NET

  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

  8. #8
    Membre chevronné
    Homme Profil pro
    edi
    Inscrit en
    Juin 2007
    Messages
    898
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Gironde (Aquitaine)

    Informations professionnelles :
    Activité : edi

    Informations forums :
    Inscription : Juin 2007
    Messages : 898
    Points : 1 915
    Points
    1 915
    Par défaut
    Est-ce-que tu dois utiliser directement les threads ou est-ce-que tu peux passer par des tasks, qui gèrent un timeout ?

  9. #9
    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
    Citation Envoyé par Noxen Voir le message
    Est-ce-que tu dois utiliser directement les threads ou est-ce-que tu peux passer par des tasks, qui gèrent un timeout ?
    Bonjour,

    Je ne connais pas les tasks, je vais regarder cela, mais le souci c'est que j'ai besoin de l'information, donc je dois attendre le résultat de l'appel de la dll lors du fonctionnement normale et même si c'est long, il me donne bien l'information. (Sauf fermeture rapide de l'application si le Dongle à été détecté).

    Pour rappel j'ai donc 2 threads l'un pour la vérification de la présence d'un Dongle et l'autre pour vérification de la présence d'une licence WEB (type DRM).
    Chaque appel de dll me renvoie l'information de la date de fin d'utilisation de la licence et du niveau d’accès accordé à l'utilisateur (User, super user, admin), en fonctionnement normale il me faut donc ces informations, je ne peux pas les casser suite à un timeout, sauf si je décide de fermer l'application alors qu'il est pile en train de vérifier la dll.
    La partie Web il l'interroge une fois lors du démarrage, mais la partie Dongle il l’interroge régulièrement, afin de ne pas démarrer plusieurs logiciels en passant les Dongle d'un PC a l'autre.

  10. #10
    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
    Je viens de tester la commande "End", c'est un peu brutal, mais cela fonctionne.
    Cela rend la main immédiatement après la fermeture de l'application même si le thread est encore bloqué sur la dll.
    Avant je ferme les treads abort et nothing.

    Dans mon cas, je ne vois pas d’inconvenant à ce fonctionnement, mais il y a peut être quelques chose qui m’échappe à la clôture du logiciel par End.

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