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

Delphi Discussion :

Thread et Application principale: Event,Message..?


Sujet :

Delphi

  1. #1
    Membre du Club Avatar de ghost942
    Profil pro
    Inscrit en
    Décembre 2002
    Messages
    112
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2002
    Messages : 112
    Points : 50
    Points
    50
    Par défaut Thread et Application principale: Event,Message..?
    Bonjour,

    Dans mon projet, j'ai plusieurs threads qui tournent et lorsque pour un thread une donnée est présente, je lève au sein de ce thread une variable "Disponible" a TRUE. Mon application principale tourne en boucle continue a attendre qu'une variable "Disponible" d'un thread soit levée pour assurer son traitement et la notifier en baissant "Disponible" a False.

    Cela fonctionne seulement l'application principale mange du temps cpu pour rien a attendre et j'aurais aimé structurer en 'evenementiel': Que le thread emette un evenement lorsqu'une donnée est disponible et que l'application principale réagisse a cet evenement.

    Je pensais utiliser TNotifyEvent pour me créer un évenement perso mais je ne vois pas comment l'employer et les exemples que je trouve sont orientés pour la conception de composant ce qui n'est pas mon cas.

    Si quelqu'un aurait une idée ?...

  2. #2
    Expert éminent sénior
    Avatar de ShaiLeTroll
    Homme Profil pro
    Développeur C++\Delphi
    Inscrit en
    Juillet 2006
    Messages
    13 459
    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 459
    Points : 24 873
    Points
    24 873
    Par défaut
    1- tu peux mettre un sleep dans la boucle d'attente ...
    2- tu peux remplacer ton booléen par un objet TCriticalSection

    Que fait ton application ? Elle recoit un message, le traite et l'envoi ?
    Si le programme est bloqué (attente disponible) quel est l'intéret d'un Thread ?
    Aide via F1 - FAQ - Guide du développeur Delphi devant un problème - Pensez-y !
    Attention Troll Méchant !
    "Quand un homme a faim, mieux vaut lui apprendre à pêcher que de lui donner un poisson" Confucius
    Mieux vaut se taire et paraître idiot, Que l'ouvrir et de le confirmer !
    L'ignorance n'excuse pas la médiocrité !

    L'expérience, c'est le nom que chacun donne à ses erreurs. (Oscar Wilde)
    Il faut avoir le courage de se tromper et d'apprendre de ses erreurs

  3. #3
    Expert éminent sénior
    Avatar de Paul TOTH
    Homme Profil pro
    Freelance
    Inscrit en
    Novembre 2002
    Messages
    8 964
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 54
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Freelance
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Novembre 2002
    Messages : 8 964
    Points : 28 445
    Points
    28 445
    Par défaut Synchroniser les thread
    Mise à part a méthode Syncrhonize du l'objet TThread, le plus simple est en général d'utiliser un PostMessage ou un SendMessage vers le Handle de la fiche principale.

    Il suffit de déclarer la gestion du message WM_USER par exemple

    type
    TForm1=...
    procedure WMUser(var Msg:TMessage); message WM_USER;

    et dans le Thread...
    SendMessage(Form1.Handle,WM_USER,x,y);
    Developpez.com: Mes articles, forum FlashPascal
    Entreprise: Execute SARL
    Le Store Excute Store

  4. #4
    Membre chevronné
    Avatar de Clorish
    Profil pro
    Inscrit en
    Juin 2003
    Messages
    2 474
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2003
    Messages : 2 474
    Points : 2 158
    Points
    2 158
    Par défaut
    On ne peux pas implementer un evenement "OnDisponible" dans le TThread qui sera appelé comme tout evenement ? Le gestionnaire etant evidement code dans le programme principal.

    PAr contre il faudra peut etre faire appel a cet evenement via une methodes synchronisée .....
    On passe du temps a vous repondre, alors soyez sympas, passez du temps ..... a vous relire !
    --
    Pourquoi tant de haine pour cette pauvre aide Delphi ????
    Aiiimezzz laaaaa .... Si-Non-Cham-Pi-Gnon !!!
    --
    Pour plus de Renseignements : Venez me rejoindre sur Msn .... Promis je mords pas

  5. #5
    Expert éminent sénior
    Avatar de Paul TOTH
    Homme Profil pro
    Freelance
    Inscrit en
    Novembre 2002
    Messages
    8 964
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 54
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Freelance
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Novembre 2002
    Messages : 8 964
    Points : 28 445
    Points
    28 445
    Par défaut
    Dans ce cas il faut faire un
    Synchronize(DoDisponible)
    avec un DoDisponible qui fera un
    if Assigned(EOnDisponible) EOnDisponible(Self)

    NB: Sychronize utilise un SendMessage pour déclencher la méthode dans le trhead principal
    Developpez.com: Mes articles, forum FlashPascal
    Entreprise: Execute SARL
    Le Store Excute Store

  6. #6
    Membre chevronné
    Avatar de Clorish
    Profil pro
    Inscrit en
    Juin 2003
    Messages
    2 474
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2003
    Messages : 2 474
    Points : 2 158
    Points
    2 158
    Par défaut
    Citation Envoyé par tothpaul
    NB: Sychronize utilise un SendMessage pour déclencher la méthode dans le trhead principal
    C'est sur que vu comme ca
    On passe du temps a vous repondre, alors soyez sympas, passez du temps ..... a vous relire !
    --
    Pourquoi tant de haine pour cette pauvre aide Delphi ????
    Aiiimezzz laaaaa .... Si-Non-Cham-Pi-Gnon !!!
    --
    Pour plus de Renseignements : Venez me rejoindre sur Msn .... Promis je mords pas

  7. #7
    Membre du Club Avatar de ghost942
    Profil pro
    Inscrit en
    Décembre 2002
    Messages
    112
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2002
    Messages : 112
    Points : 50
    Points
    50
    Par défaut
    Les threads opérent des requêtes HTTP en fait et les données arrivent de manière asynchrone. Mon application principale ne peut pas 'sleeper' non plus car elle doit réagir rapidement.

    Je pensais plutot a avoir une méthode evenementielle style Tform1.OnDisponible(Send:Tobject)

  8. #8
    Membre chevronné
    Avatar de Clorish
    Profil pro
    Inscrit en
    Juin 2003
    Messages
    2 474
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2003
    Messages : 2 474
    Points : 2 158
    Points
    2 158
    Par défaut
    Si ce que tu cherche est la rapiditee de reaction, tu peux meme directement faire appel a une procedure du thread principal ... toujours avec un passage par synchronize.
    On passe du temps a vous repondre, alors soyez sympas, passez du temps ..... a vous relire !
    --
    Pourquoi tant de haine pour cette pauvre aide Delphi ????
    Aiiimezzz laaaaa .... Si-Non-Cham-Pi-Gnon !!!
    --
    Pour plus de Renseignements : Venez me rejoindre sur Msn .... Promis je mords pas

  9. #9
    Expert éminent sénior
    Avatar de Paul TOTH
    Homme Profil pro
    Freelance
    Inscrit en
    Novembre 2002
    Messages
    8 964
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 54
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Freelance
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Novembre 2002
    Messages : 8 964
    Points : 28 445
    Points
    28 445
    Par défaut
    Citation Envoyé par ghost942
    Les threads opérent des requêtes HTTP en fait et les données arrivent de manière asynchrone. Mon application principale ne peut pas 'sleeper' non plus car elle doit réagir rapidement.

    Je pensais plutot a avoir une méthode evenementielle style Tform1.OnDisponible(Send:Tobject)
    ça ne change rien au problème, le thread récupère la page web, et déclenche l'événement soit par un SendMessage(Form1.Handle,WM_USER,0,integer(Self)), soit comme expliqué plus haut avec un Synchronize...

    maintenant, si le Thread se termine après sa requête, tu peux aussi utiliser un Section Critique pour place la réponse dans un liste de Form1...et sur le OnIdle ou suivant un Timer vérifer que la liste n'est pas vide.

    enfin bref, y'a des tas de façon de voir Sous Windows le SendMessage restant à mes yeux le plus simple
    Developpez.com: Mes articles, forum FlashPascal
    Entreprise: Execute SARL
    Le Store Excute Store

  10. #10
    Membre du Club Avatar de ghost942
    Profil pro
    Inscrit en
    Décembre 2002
    Messages
    112
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2002
    Messages : 112
    Points : 50
    Points
    50
    Par défaut
    Seulement avec Synchronize(), "L'exécution du thread est interrompue tant que Method s'exécute dans le thread VCL principal" (DelphiHelp). Or j'ai envie que mon Thread continue son bonhonme de chemin pendant ce temps la!

    Oui c'est vrai que justement il existe mille et une facons de faire la chose...et la difficulté est de trouver celle la mieux adaptée!

  11. #11
    Membre du Club Avatar de ghost942
    Profil pro
    Inscrit en
    Décembre 2002
    Messages
    112
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2002
    Messages : 112
    Points : 50
    Points
    50
    Par défaut
    Je vais peut etre m'orienter vers les Messages alors.

  12. #12
    Membre chevronné
    Avatar de Clorish
    Profil pro
    Inscrit en
    Juin 2003
    Messages
    2 474
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2003
    Messages : 2 474
    Points : 2 158
    Points
    2 158
    Par défaut
    Citation Envoyé par ghost942
    Seulement avec Synchronize(), "L'exécution du thread est interrompue tant que Method s'exécute dans le thread VCL principal" (DelphiHelp). Or j'ai envie que mon Thread continue son bonhonme de chemin pendant ce temps la!
    alors send message ... comme ca l'evenement est traité au plus tot.

    Ou alors, tu peux peut passer par un 3e Thread qui s'occupe de lancer la procedure souhaite dans le thread principal et d'attendre sa fin
    Utilise la fonction CreateThread de l'api windows .... ideale pour ce genre de traitement ponctuel.
    On passe du temps a vous repondre, alors soyez sympas, passez du temps ..... a vous relire !
    --
    Pourquoi tant de haine pour cette pauvre aide Delphi ????
    Aiiimezzz laaaaa .... Si-Non-Cham-Pi-Gnon !!!
    --
    Pour plus de Renseignements : Venez me rejoindre sur Msn .... Promis je mords pas

  13. #13
    Membre du Club Avatar de ghost942
    Profil pro
    Inscrit en
    Décembre 2002
    Messages
    112
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2002
    Messages : 112
    Points : 50
    Points
    50
    Par défaut
    PostMessage plutot non? SendMessage attend alors que Post non?!

  14. #14
    Expert éminent sénior
    Avatar de Paul TOTH
    Homme Profil pro
    Freelance
    Inscrit en
    Novembre 2002
    Messages
    8 964
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 54
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Freelance
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Novembre 2002
    Messages : 8 964
    Points : 28 445
    Points
    28 445
    Par défaut
    Ok, voici un exemple de ce que tu peux faire

    <début du thread>
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
      repeat
        Page:=TStringList.Create;
        LireLaPage(Page);
        PostMessage(Form1.Handle,WM_USER,0,integer(Page));
        // NB: le PostMessage n'est pas bloquant
      until JaiPlusRienAFaire;
    <thread principal>
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
     
    procedure Tform1.WMUser(var Msg:TMessage); // message WM_USER
    var
      List:TStringList;
    begin
      List:=TStringList(Msg.lParam);
      try
        <faire quelquechose de ce StringList>
      finally
        List.Free; // car le Thread crée une nouvelle instance à chaque fois !
      end;
    end;
    Mais il n'est pas forcément judicieux de traiter la page dans le Thread principal...
    Developpez.com: Mes articles, forum FlashPascal
    Entreprise: Execute SARL
    Le Store Excute Store

  15. #15
    Membre chevronné
    Avatar de Clorish
    Profil pro
    Inscrit en
    Juin 2003
    Messages
    2 474
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2003
    Messages : 2 474
    Points : 2 158
    Points
    2 158
    Par défaut
    Citation Envoyé par ghost942
    PostMessage plutot non? SendMessage attend alors que Post non?!
    Si tu le dit
    Moi je manipule pas encore trop ca
    Je suis juste les "dire" de Paul
    On passe du temps a vous repondre, alors soyez sympas, passez du temps ..... a vous relire !
    --
    Pourquoi tant de haine pour cette pauvre aide Delphi ????
    Aiiimezzz laaaaa .... Si-Non-Cham-Pi-Gnon !!!
    --
    Pour plus de Renseignements : Venez me rejoindre sur Msn .... Promis je mords pas

  16. #16
    Membre émérite Avatar de edam
    Homme Profil pro
    Développeur Delphi/c++/Omnis
    Inscrit en
    Décembre 2003
    Messages
    1 894
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Maroc

    Informations professionnelles :
    Activité : Développeur Delphi/c++/Omnis
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Décembre 2003
    Messages : 1 894
    Points : 2 771
    Points
    2 771
    PAS DE DESTIN, C'EST CE QUE NOUS FAISONS

  17. #17
    Expert éminent sénior
    Avatar de ShaiLeTroll
    Homme Profil pro
    Développeur C++\Delphi
    Inscrit en
    Juillet 2006
    Messages
    13 459
    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 459
    Points : 24 873
    Points
    24 873
    Par défaut
    le lien d'Edam, est excellent pour ce sujet !

    Citation Envoyé par tothpaul
    Dans ce cas il faut faire un
    Synchronize(DoDisponible)
    avec un DoDisponible qui fera un
    if Assigned(EOnDisponible) EOnDisponible(Self)
    Tout à fait d'accord pour le DoDisponible, j'ai écrit ce genre de chose

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    type
      TFileMessageEvent = procedure(Sender: TObject; const Messages: string) of object;
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    procedure TXXXForm.FileChange(Sender: TObject; const Messages: string);
    begin
      if (GetWindowLong(HandleByClass, GWL_STYLE) and WS_VISIBLE) = WS_VISIBLE then
        Exit;
     
      IdleCount := 0;
      TreatMessages(Messages); // On peut aussi faire un SendMessage si l'on ne veut pas bloquer le thread ...
    end;
    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
    procedure TXXXThread.Execute();
    var
       HandleNotification: THandle;
       Delay: Cardinal;
    begin
       ReadLastMessages;
     
       Delay := 1000;
       Sleep(Delay);
     
       HandleNotification := FindFirstChangeNotification(PChar(FDirName), True, FILE_NOTIFY_CHANGE_SIZE);
       try
          while not Terminated do
          begin
             case WaitForSingleObject(HandleNotification, Delay) of
                WAIT_OBJECT_0 :
                   begin
                     ReadLastMessages;
                     Synchronize(DoChange);
                     Delay := 1000;
                     FindNextChangeNotification(HandleNotification);
                   end;
                WAIT_ABANDONED : Terminate;
                WAIT_TIMEOUT :
                   begin
                      Synchronize(DoIdle);
                      Delay := 200;
                   end;
             end;
          end;
       finally
          FindCloseChangeNotification(HandleNotification);
       end;
    end;
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    procedure TXXXThread.DoIdle();
    begin
       try
          if Assigned(FOnIdle) then
          begin
            FOnIdle(Self, ...);
          end;
       except
          on E: Exception do
            OutputDebugString(PChar(Format('Error %s On TXXX.DoIdle: "%s"', [E.ClassName, E.Message])));
       end;
    end;
    Si non il faudrait voir sur PostThreadMessage qui sera plus fonctionnel que PostMessage ... Ensuite ceci n'est pas exacte :
    NB: Sychronize utilise un SendMessage pour déclencher la méthode dans le trhead principal
    Synchronise ajoute le pointeur de méthode dans une liste de méthode, ensuite dans la boucle run, lorsqu'il n'y a pas de messages windows à traiter, il y a un appel à la méthode Classes.CheckSynchronize qui prend le premier item de la list et lance la méthode posté par Thread.Synchronize, pendant ce temps, le Thread attend avec un WaitForSingleObject le signal de fin ...
    Aide via F1 - FAQ - Guide du développeur Delphi devant un problème - Pensez-y !
    Attention Troll Méchant !
    "Quand un homme a faim, mieux vaut lui apprendre à pêcher que de lui donner un poisson" Confucius
    Mieux vaut se taire et paraître idiot, Que l'ouvrir et de le confirmer !
    L'ignorance n'excuse pas la médiocrité !

    L'expérience, c'est le nom que chacun donne à ses erreurs. (Oscar Wilde)
    Il faut avoir le courage de se tromper et d'apprendre de ses erreurs

  18. #18
    Membre du Club Avatar de ghost942
    Profil pro
    Inscrit en
    Décembre 2002
    Messages
    112
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2002
    Messages : 112
    Points : 50
    Points
    50
    Par défaut
    Voila, j'suis passé par les messages.

    Chaque thread lancera un PostMessage() une fois qu'une donnée sera disponible et l'application principale avec DefaultHandler() réagira aux messages. C'est plus propre et plus souple je trouve qu'une boucle infinie.

    Merci pour vos aides respectives!

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

Discussions similaires

  1. Utilisation de Thread avec application principale
    Par mohammed.badre dans le forum Débuter
    Réponses: 1
    Dernier message: 24/10/2012, 18h16
  2. application pour envoi message pc vers pc sous reseau
    Par amine0027 dans le forum Delphi
    Réponses: 3
    Dernier message: 28/04/2007, 09h20
  3. [Thread]Problème d'envoie de message
    Par homeostasie dans le forum MFC
    Réponses: 4
    Dernier message: 15/02/2007, 09h26
  4. Utiliser les threads dans application Struts
    Par rach375 dans le forum Struts 1
    Réponses: 7
    Dernier message: 18/09/2006, 11h32
  5. Réponses: 1
    Dernier message: 05/05/2006, 14h29

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