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

Langage Delphi Discussion :

arrêter un TEVent


Sujet :

Langage Delphi

  1. #1
    Membre expert

    Homme Profil pro
    Développeur informatique
    Inscrit en
    Novembre 2007
    Messages
    3 487
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 63
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Novembre 2007
    Messages : 3 487
    Points : 3 120
    Points
    3 120
    Par défaut arrêter un TEVent
    Bonjour

    Le code suivant fonctionne et fait ce que j'attends.
    Par contre, je ne comprends pas pourquoi il ne passa jamais dans le wrAbandoned.
    J'ai tenté un Release, un Free, mais ça ne passe jamais dans l'envoi du mot Terminé.
    Est-ce que je fais mal quelque chose ?

    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
     
        TThread.CreateAnonymousThread(
          procedure
          var
            Status: TWaitResult;
            i: Integer;
            S: string;
            Termine: Boolean;
          begin
            Termine := False;
            repeat
     
              case Evt.WaitFor(INFINITE) of
                wrSignaled:
                  begin
                    Codesite.Send('signalé');
                  end;
                wrAbandoned:
                begin
                  Termine := True;
                  Codesite.Send('Terminé');
                end;
              end;
              Evt.ResetEvent;
              Codesite.Send('on relance l''écoute');
     
            until Termine;
          end).Start;

  2. #2
    Expert éminent sénior
    Avatar de ShaiLeTroll
    Homme Profil pro
    Développeur C++\Delphi
    Inscrit en
    Juillet 2006
    Messages
    13 586
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Seine Saint Denis (Île de France)

    Informations professionnelles :
    Activité : Développeur C++\Delphi
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juillet 2006
    Messages : 13 586
    Points : 25 262
    Points
    25 262
    Par défaut
    Un TEvent se s'arrête pas, le but est plutôt de faire un SetEvent pour obtenir un wrSignaled.
    Je ne pratique pas le thread anonyme, j'utilise aussi wrTimeOut pour gérer un état Idle du thread.

    la gestion de wrAbandoned est plutôt à considéré comme une défaillance, l'objet TEvent libéré de façon imprévu alors que le thread fonctionne encore
    Dans ton code, tu pourrais avoir une VA sur Evt.ResetEvent en cas de wrAbandoned donc utiliser la libération ainsi semble une source d'erreur.

    Cela doit émettre un wrAbandoned lors du Free mais uniquement avec un TimeOut différent de INFINITE (je ne l'utilise jamais, car j'inclus souvent un Thread Keeper)

    J'utilise parfois WaitForMultiple pour avoir plusieurs TEvent, celui du cycle par exemple pour le dépilement d'une FIFO et celui d'abandon, les deux déclenchés par SetEvent

    Comme je fais des Thread explicite, je peux aussi surcharge le TerminatedSet, ainsi un wrSignaled + not Terminated = cycle et wrSignaled + Terminated = abandon
    voir ce code qui illustre ce cas : https://www.developpez.net/forums/d1...t/#post9620723

    Ce code pour un autre sujet devrait t'intéresser même si il est avec un thread explicite : https://www.developpez.net/forums/d2.../#post11863712


    Si tu es en VCL : WAIT_ABANDONED - https://learn.microsoft.com/en-us/wi...orsingleobject

    The specified object is a mutex object that was not released by the thread that owned the mutex object before the owning thread terminated. Ownership of the mutex object is granted to the calling thread and the mutex state is set to nonsignaled.
    If the mutex was protecting persistent state information, you should check it for consistency.
    If dwMilliseconds is INFINITE, the function will return only when the object is signaled.

    Si tu es en FMX, il te faudra vérifier l'implémentation du TEvent selon l'OS cible pour voir si utilisé wrSignaled est pertinent, personnellement, je ne baserais pas mon développement sur cela en dehors d'une gestion de la défaillance (faudrait s'inquiéter de l'architecture du code si cela se produisait, je l'ai jamais vu en pratique après 20 ans de programmation multi-thread)

  3. #3
    Rédacteur/Modérateur
    Avatar de Andnotor
    Inscrit en
    Septembre 2008
    Messages
    5 763
    Détails du profil
    Informations personnelles :
    Localisation : Autre

    Informations forums :
    Inscription : Septembre 2008
    Messages : 5 763
    Points : 13 381
    Points
    13 381
    Par défaut
    wrAbandoned ne peut jamais survenir sur un event puisque ça concerne spécifiquement les mutex (c'est bien spécifié dans l'extrait de ShaiLeTroll)

    wrAbandoned survient lorsqu'un thread se termine sans avoir pour autant libéré le mutex qu'il avait acquis. Il faut considérer cet état comme instable puisqu'on ne peut être sûr que l'action ayant entraîné le verrouillage soit allé à son terme (et que la donnée protégée soit valide).

    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
    procedure TForm1.FormCreate(Sender: TObject);
    begin
      Mutex := TMutex.Create(nil, false, '');
     
      TThread.CreateAnonymousThread(
        procedure
        begin
          // Verrouillage
          Mutex.Acquire;
     
          // Pour être sûr que le 2ème thread
          // est démarré et en attente
          Sleep(1000);
     
          // Se termine sans libération
        end).Start;
     
      TThread.CreateAnonymousThread(
        procedure
        begin
          case Mutex.WaitFor(INFINITE) of
            wrSignaled  : Codesite.Send('signalé');
            wrAbandoned : Codesite.Send('Abandonné');
          end;
        end).Start;
    end;

  4. #4
    Membre expert

    Homme Profil pro
    Développeur informatique
    Inscrit en
    Novembre 2007
    Messages
    3 487
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 63
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Novembre 2007
    Messages : 3 487
    Points : 3 120
    Points
    3 120
    Par défaut
    Je suis effectivement en VCL.

    Le SetEvent, je l'utilise justement depuis un autre thread qui indique à celui-ci qu'il a une action à faire (j'ai simplifié le code mis ici).

    Je pensais que le wrAbandoned pouvait être déclenché d'une façon ou d'une autre mais tu m'as détrompé.
    Une variable au même niveau que la déclaration du TEvent pourrait faire l'affaire effectivement en lé gérant dans wrSignaled.
    Je vais étudier les codes sources dans les liens que tu m'as indiqué.

    Comme d'habitude, un grand merci pour ton aide.

  5. #5
    Membre expert

    Homme Profil pro
    Développeur informatique
    Inscrit en
    Novembre 2007
    Messages
    3 487
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 63
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Novembre 2007
    Messages : 3 487
    Points : 3 120
    Points
    3 120
    Par défaut
    @Andnotor

    Je n'avais pas de mutex là-dedans.
    En fait, j'ai un thread qui fait des traitements sur des fichiers et le second avec le TEvent qui est déclenché quand un traitement secondaire est à faire sur chaque fichier traité. La synchro entre les 2 se fait bien (visuellement dans Codesite).
    Mais je ne comprenais pas pourquoi je ne passais jamais dans le cas 'Terminé'.
    Au vu des vos explications, je comprends mieux maintenant

  6. #6
    Rédacteur/Modérateur
    Avatar de Andnotor
    Inscrit en
    Septembre 2008
    Messages
    5 763
    Détails du profil
    Informations personnelles :
    Localisation : Autre

    Informations forums :
    Inscription : Septembre 2008
    Messages : 5 763
    Points : 13 381
    Points
    13 381
    Par défaut
    Citation Envoyé par Papy214 Voir le message
    Je n'avais pas de mutex là-dedans.
    J'ai bien vu .

Discussions similaires

  1. Réponses: 0
    Dernier message: 20/03/2019, 09h17
  2. Réponses: 2
    Dernier message: 07/12/2007, 13h31

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