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 :

événement dans un thread


Sujet :

Langage Delphi

  1. #1
    Membre du Club
    Profil pro
    Inscrit en
    Avril 2002
    Messages
    121
    Détails du profil
    Informations personnelles :
    Âge : 51
    Localisation : France, Isère (Rhône Alpes)

    Informations forums :
    Inscription : Avril 2002
    Messages : 121
    Points : 48
    Points
    48
    Par défaut événement dans un thread
    Bonjour.
    Je viens d'utiliser les threads pour la première fois.
    Dans mon thread, j'établie une connexion avec un serveur,
    je remonter un fichier en tcp. (pas en ftp, mais avec un protocole propriétaire)
    Tout fonctionne bien.


    Le fichier est remonté en plusieurs paquets.
    A chaque paquet, je souhaiterais déclencher un evt qui donne la taille envoyé et la taille totale.

    Dans cet evenement, je souhaiterais dans le thread principal afficher la progression dans un composant TLabel.
    Mais le label ne se rafraichit pas.
    Ou est le pb ?
    J'ai aussi mis une progressbar, elle se rafraichit bien

    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
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
     
    procedure TUploadThread.Execute;
    begin
     if not Connexion then exit;
     if not Upload then exit;
     DeConnexion;
    end;
     
    procedure TUploadThread.callOnPacketSent();
    begin
     if Assigned(fOnPacketSent)then
     begin
      fOnPacketSent(LenSent,LenTot)
     end;
    end;
     
    function TUploadThread.Upload():boolean;
    var
    temp,chaineIconv:string;
    code3:string;
    LenToSend:integer;
    begin
     result := false;
     fStream.LoadFromFile(ffileSrc);
     temp := TRAME_UPLOAD_THREAD;
     CnvA2E(temp);
     chaineIconv := temp+ ShortToString(length(fFileDest));
     temp := fFileDest;
     cnvA2E(temp);
     chaineIconv := chaineIconv + temp;
     fTcpClient.Sendln(chaineIconv,'');
     code3 := receptionAlpha(fTcpClient,3);
     if(Code3 =TRAME_MESSAGE_ERREUR)then
     begin
      if assigned(fOnErrorUpload)then
      begin
       fOnErrorUpload(teFileName);
      end;
      exit;
     end;
     result := true;
     LenSent := 0;
     fStream.Seek(0,soFromBeginning);
     LenTot :=  fStream.Size;
     while(LenSent < LenTot)do
     begin
      LenToSend := fStream.Size - LenSent;
      if(LenToSend) > fPacketSize then
      begin
       LenToSend := fPacketSize;
      end;
      SetString(temp,nil,lenToSend);
      fStream.Read(temp[1],lenToSend);
      chaineIconv := #1 + inttostring(LenToSend) +temp;
      fTcpClient.Sendln(chaineIConv,'');
      LenSent := LenSent + LenToSend;
      code3 := receptionAlpha(fTcpClient,3);
      if(Code3 =TRAME_MESSAGE_ERREUR)then
      begin
       if assigned(fOnErrorUpload)then
       begin
        fOnErrorUpload(teWrite);
       end;
       exit;
      end;
     
      Synchronize(callOnPacketSent);
     
      if(fToStop)then
      begin
       chaineIconv := #0;
       fTcpClient.Sendln(chaineIConv,'');
       receptionAlpha(fTcpClient,3);
      end;
     end;
     chaineIconv := #0;
     fTcpClient.Sendln(chaineIConv,'');
     code3 := receptionAlpha(fTcpClient,3);
     if(Code3 =TRAME_MESSAGE_ERREUR)then
     begin
      if assigned(fOnErrorUpload)then
      begin
       fOnErrorUpload(teSync);
      end;
      exit;
     end;
     Synchronize(callOnEndUpload);
     
     
     
    end;
    //fonction appelée dans l'evenement onPacketSent 
     
    procedure TFormDesigner.MySent(sent:integer;Total:integer);
    begin
     Label1.Caption := inttostr(sent)+'/'+inttostr(total);
     ProgressBar1.Max := total;
     ProgressBar1.Position := sent;
    end;

  2. #2
    Modérateur
    Avatar de tourlourou
    Homme Profil pro
    Biologiste ; Progr(amateur)
    Inscrit en
    Mars 2005
    Messages
    3 875
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 61
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Biologiste ; Progr(amateur)

    Informations forums :
    Inscription : Mars 2005
    Messages : 3 875
    Points : 11 366
    Points
    11 366
    Billets dans le blog
    6
    Par défaut
    Idem en ajoutant (Label1.)Refresh ou Repaint dans MySent ?
    ou Application.ProcessMessages ?

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

    Informations forums :
    Inscription : Septembre 2008
    Messages : 5 761
    Points : 13 368
    Points
    13 368
    Par défaut
    Il ne faut pas accéder directement à la VCL depuis un thread secondaire.
    A la place, utilise PostMessage avec tes positions actuelle et Max en paramètres.

    Même si c'était fait pour du download, tu as un exemple ici (tout ce qui concerne WM_DOWNLOADPROGRESS).

  4. #4
    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
    AndNotOr, il a utilisé Synchronize pour lancer ses events, c'est donc sans risque !
    Mais PostThreadMessage ou PostMessage conserve l'avantage de la rapidité (le traitement d'affichage ne ralentissant pas le traitement)

    la ProgressBar est un control windows, il se rafraichit automatiquement dès que l'on le modifie
    le Label est un control graphique delphi, il faut le dessiner explicitement ou ajouter un Application.ProcessMessages (à éviter pour les performances du thread)

  5. #5
    Membre du Club
    Profil pro
    Inscrit en
    Avril 2002
    Messages
    121
    Détails du profil
    Informations personnelles :
    Âge : 51
    Localisation : France, Isère (Rhône Alpes)

    Informations forums :
    Inscription : Avril 2002
    Messages : 121
    Points : 48
    Points
    48
    Par défaut A moitié résolu
    Bonjour. Merci pour vos réponses.
    Je viens de constater qu'en enlevant la propriété mdiform de la fenêtre principale, le pb ne se produit plus.


    j'ai fait un autre test dans une nouvelle appli , juste un timer et une fenetre mdi mere , je constate le meme pb.

    Le pb ne vient donc sans doute pas du thread, désolé pour le dérangement.

  6. #6
    Membre expert
    Avatar de LadyWasky
    Femme Profil pro
    Inscrit en
    Juin 2004
    Messages
    2 932
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Âge : 54
    Localisation : France, Hauts de Seine (Île de France)

    Informations forums :
    Inscription : Juin 2004
    Messages : 2 932
    Points : 3 565
    Points
    3 565
    Par défaut
    Citation Envoyé par ShaiLeTroll Voir le message
    AndNotOr, il a utilisé Synchronize pour lancer ses events, c'est donc sans risque !
    Mais PostThreadMessage ou PostMessage conserve l'avantage de la rapidité (le traitement d'affichage ne ralentissant pas le traitement)

    la ProgressBar est un control windows, il se rafraichit automatiquement dès que l'on le modifie
    le Label est un control graphique delphi, il faut le dessiner explicitement ou ajouter un Application.ProcessMessages (à éviter pour les performances du thread)
    Tout à fait d'accord avec toi

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

    Informations forums :
    Inscription : Septembre 2008
    Messages : 5 761
    Points : 13 368
    Points
    13 368
    Par défaut
    Citation Envoyé par ShaiLeTroll Voir le message
    AndNotOr, il a utilisé Synchronize pour lancer ses events, c'est donc sans risque !
    J'ai répondu le soir sans relire le code. Le premier posté n'avait pas de synchronize (ou alors j'ai rêvé)

  8. #8
    Membre éprouvé
    Avatar de Montor
    Homme Profil pro
    Autre
    Inscrit en
    Avril 2008
    Messages
    879
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Autre

    Informations professionnelles :
    Activité : Autre

    Informations forums :
    Inscription : Avril 2008
    Messages : 879
    Points : 963
    Points
    963
    Par défaut
    invalidate ...

    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
    var Step :integer =0;
    procedure TFormDesigner.MySent(sent:integer;Total:integer);
    begin
     
      if(Step = (sent*100 div Total ))then
          Exit;
     
       Step:=sent*100 div Total ;
     
     Label1.Caption := inttostr(sent)+'/'+inttostr(total);
     ProgressBar1.Max := total;
     ProgressBar1.Position := sent;
     
     invalidate();
     
    end;

  9. #9
    Membre du Club
    Profil pro
    Inscrit en
    Avril 2002
    Messages
    121
    Détails du profil
    Informations personnelles :
    Âge : 51
    Localisation : France, Isère (Rhône Alpes)

    Informations forums :
    Inscription : Avril 2002
    Messages : 121
    Points : 48
    Points
    48
    Par défaut
    andnotor :Tu n'as pas rêvé, j'ai ajouté le synchronize après.
    Montor: Le invalidate fonctionne, mais fait scintiller la fenêtre.
    Mais il s'agit simplement d'un pb avec la fenetre mdi mere, ce qui m'est égal puisque j'avais mis le label juste pour vérifier que tout se passe bien.

    Merci de vos réponses

Discussions similaires

  1. Gestion des évènements dans un thread
    Par kashikai dans le forum SDL
    Réponses: 0
    Dernier message: 25/05/2009, 14h32
  2. L'évènement semble être déclenché dans un thread séparé
    Par Skalp dans le forum Général Dotnet
    Réponses: 3
    Dernier message: 04/07/2008, 14h17
  3. Réponses: 10
    Dernier message: 21/02/2007, 20h16
  4. Gestion des message windows dans les threads
    Par billyboy dans le forum Windows
    Réponses: 5
    Dernier message: 06/10/2003, 17h25
  5. Modifier un événement dans le code
    Par HT dans le forum Langage
    Réponses: 6
    Dernier message: 20/06/2003, 09h46

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