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

 Delphi Discussion :

[D7] Arrêter un Thread


Sujet :

Delphi

  1. #1
    Membre chevronné
    Avatar de Charly910
    Homme Profil pro
    Ingénieur TP
    Inscrit en
    décembre 2006
    Messages
    1 483
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur TP
    Secteur : Bâtiment Travaux Publics

    Informations forums :
    Inscription : décembre 2006
    Messages : 1 483
    Points : 2 235
    Points
    2 235
    Par défaut [D7] Arrêter un Thread
    Bonjour,
    Question déjà posée, mais pour laquelle je n'ai pas trouvé de réponse satisfaisante :

    Je lance un Thread avec cette procédure, pour un traitement qui peut être très long, voire bloquant :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    var
        MThrd :  TPersoThread  ;
    ...
    { =============================================================== }
    procedure TF_Princ.ExecThreadClick(Sender: TObject);
    begin
      MThrd := TPersoThread.Create(True) ;
      MThrd.Execute ;
      MThrd.Free ;
    end;
    et j'essaye de l'arrêter avant la fin du traitement avec cette procédure :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    procedure TF_Princ.StopThreadClick(Sender: TObject);
    begin
      TerminateThread(MThrd.Handle, 0);   // Essai de Kill brutal du Thread : ne marche pas
    //   Autres essais infructueux ...
    //  MThrd.Destroy ;
    //  MThrd.Suspend ;
    //  MThrd.Terminate ;  // ne fonctionne pas car je ne teste pas Terminated 
    end;
    Le Thread consiste à se connecter à un serveur, et à télécharger de nombreux fichiers :

    Code : 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
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    unit Thread1 ;
    interface
    uses Windows, Classes, SysUtils, Forms, mmSystem ;
     
    type
      TPersoThread = class(TThread)
      private
        procedure CentralControl;
      public
        constructor Create(CreateSuspended:boolean);
        destructor Destroy; override;
        procedure Execute; override;
      protected
      end;
     
    implementation
     
    Uses Princ, MyHttp ;
     
    Var
        Aspirateur  : TAspirateur;
        ListFic  : TStringList ;
    { =============================================================== }
    constructor TPersoThread.Create(CreateSuspended:boolean);
    begin
      inherited Create(CreateSuspended) ;
      FreeOnTerminate := True ;
      Priority := tpNormal ;
    end;
    { =============================================================== }
    destructor TPersoThread.Destroy;
    begin
      //décharge la mémoire des objets
      If Aspirateur <> Nil Then FreeAndNil(Aspirateur) ;
      If ListFic <> Nil Then FreeAndNil(ListFic) ;
      inherited;
    end;
    { =============================================================== }
    procedure TPersoThread.CentralControl;
    begin
    //     Traitement long, avec connection à un serveur et
    //     Téléchargement de nombreux fichiers 
     
      ....
      FreeAndNil(Aspirateur) ;
      F_Princ.MajBouton(True) ;
        end;
    end;
    { =============================================================== }
    procedure TPersoThread.Execute;
    begin
        Synchronize(CentralControl);
    end;
    { =============================================================== }
    end.
    il arrive que le traitement soit très long et que l'on veuille l'arrêter, même "brutalement". Je ne peux pas utiliser Terminate car il n'y a pas de boucle dans le Thread ou l'on peut tester Terminated. On peut faire un kill du Thread, car il n'y a pas de données à sauvegarder, mais il faudrait libérer les objets créés (?).

    Comment faire, car TerminateThread n'a pas l'air de fonctionner ?

    Merci
    A+
    Charly

  2. #2
    Rédacteur/Modérateur
    Avatar de Andnotor
    Profil pro
    Inscrit en
    septembre 2008
    Messages
    4 823
    Détails du profil
    Informations personnelles :
    Localisation : Suisse

    Informations forums :
    Inscription : septembre 2008
    Messages : 4 823
    Points : 10 320
    Points
    10 320
    Par défaut
    Tu crées le thread en état suspendu mais ne le démarre pas (Resume). Il ne tourne tout simplement pas !
    Tu appelles la méthode Execute depuis le thread principal. On appelle jamais directement cette méthode qui est le point d'entrée du thread et invoquée par le système.
    Tu libères immédiatement MThrd. Le thread n'aurait de toute façon aucune chance de démarrer.
    Soit tu gères la durée de vie de l'objet TThread toi-même (Free), soit il se libère automatiquement (FreeOnTerminate) mais pas les deux.
    Même s'il s'exécutait, CentralControl est lancé dans le thread principal du fait du synchronize ! Il n'a dès lors aucun intérêt et ne fait que retarder le début du téléchargement.

    En gros, tout est faux

    Tu télécharges de "nombreux fichiers", tu as donc une boucle non ?



    ps : TerminateThread ne devrait en soi jamais être utilisé.

  3. #3
    Membre chevronné
    Avatar de Charly910
    Homme Profil pro
    Ingénieur TP
    Inscrit en
    décembre 2006
    Messages
    1 483
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur TP
    Secteur : Bâtiment Travaux Publics

    Informations forums :
    Inscription : décembre 2006
    Messages : 1 483
    Points : 2 235
    Points
    2 235
    Par défaut
    Merci Andnotor,

    je vais essayer de "dépatouiller" tout cela !

    j'ai une boucle pour télécharger les fichiers, mais souvent ce qui est long c'est la connexion au serveur (que je voudrais arrêter).

    Ce qui me semble bizarre avec mon code, c'est que le traitement se lance bien et s'exécute jusqu'à la fin. Mais impossible de l'arrêter en cours ...

    A+
    Charly

  4. #4
    Membre chevronné
    Avatar de Charly910
    Homme Profil pro
    Ingénieur TP
    Inscrit en
    décembre 2006
    Messages
    1 483
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur TP
    Secteur : Bâtiment Travaux Publics

    Informations forums :
    Inscription : décembre 2006
    Messages : 1 483
    Points : 2 235
    Points
    2 235
    Par défaut
    Bon, j'ai supprimé CentralControl, j'ai placé son code dans Execute et j'ai ajouté des "If Terminated" dans la boucle de téléchargement des fichiers.

    J'ai modifié les appels au Thread commz suit :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    procedure TF_Princ.ExecThreadClick(Sender: TObject);
    begin
      MThrd := TPersoThread.Create(True) ;
      MThrd.Resume ;
    // ou bien directement  MThrd := TPersoThread.Create(False) ;
    end;
     
    procedure TF_Princ.StopThreadClick(Sender: TObject);
    begin
        MThrd.Terminate ;
    end;
    Cela fonctionne bien, mais je ne peux pas arrêter le Thread lors de la connexion au serveur. Je vais donc renoncer à la possibilité d'arrêter le Thread en cours car ce qui peut prendre du temps c'est la connexion !

    Merci pour tes conseils qui m'ont beaucoup appris sur les Threads.

    A+
    Charly

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Arrêter un thread en python ?
    Par fanou31 dans le forum Général Python
    Réponses: 7
    Dernier message: 23/06/2013, 19h15
  2. Réponses: 2
    Dernier message: 05/10/2006, 18h56
  3. [Thread] arrêter un thread
    Par melvar dans le forum APIs
    Réponses: 4
    Dernier message: 10/04/2006, 19h06
  4. Réponses: 18
    Dernier message: 06/04/2005, 15h09
  5. Arrêter une Thread brutalement!
    Par Rodrigue dans le forum C++Builder
    Réponses: 2
    Dernier message: 18/01/2004, 22h29

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