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 :

Traitement long dans Synchronize après Itask


Sujet :

Langage Delphi

  1. #1
    Débutant
    Profil pro
    Inscrit en
    juillet 2003
    Messages
    878
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : juillet 2003
    Messages : 878
    Points : 323
    Points
    323
    Par défaut Traitement long dans Synchronize après Itask
    bonsoir,

    afin d'éviter l'application de se figer, je fais des requêtes http dans un Itask
    une fois les données reçu, je mets à jour une listbox en passant par Synchronize
    tout se passait bien, sauf que maintenant les données que je reçois sont assez volumineuse, et le passage dans le Tlistbox fige l'application (environ 5000 items)
    si je laisse le passage des données dans le Tlistbox dans Itask l'application ne fige pas, mais vous savez, il y a des sacades à cause du thread (d'ou l'obligation de passer par Synchronise)

    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
     
       aTask := TTask.Create(
       procedure
       begin
     
         s := IdHTTP1.Get('requête_php');
     
         var  JSon  := TJSonObject.ParseJSONValue(s);
     
         TThread.Synchronize(TThread.Current,
           procedure
           begin
     
     
             for I := 0 to TJSONArray(JSon).Count-1 do
             begin
     
    		 // récupération des données
     
               TJSONArray(JSon)[i].TryGetValue<string>('id_commande', id_commande);
     
    		  // ajout dans listbox
     
               listbox1.Items.Add(id_commande);
     
             end;
     
     
           end);
     
       end);
       aTask.Start;
    ce n'est pas la boucle de récupération du json qui fige, mais bien l'entrée dans le Tlistbox (car j'ai essayé en le retirant)
    une idée svp ?

  2. #2
    Membre expert

    Homme Profil pro
    Développeur informatique
    Inscrit en
    novembre 2006
    Messages
    617
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Deux Sèvres (Poitou Charente)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Finance

    Informations forums :
    Inscription : novembre 2006
    Messages : 617
    Points : 3 297
    Points
    3 297
    Billets dans le blog
    2
    Par défaut
    Bonsoir,

    Avez vous essayé en mettant avant le for un
    et après le for un
    Cela permet d'éviter de redessiner le listbox1 à chaque insertion d'un item.
    Mon site - Mes tutoriels - GitHub - N'oubliez pas de consulter les FAQ Delphi et les cours et tutoriels Delphi

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

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

    Informations forums :
    Inscription : novembre 2002
    Messages : 8 510
    Points : 27 558
    Points
    27 558
    Par défaut
    pour ce genre de cas je décode le JSON dans le Thread dans un TStringList (ou liste plus évoluée si besoin est), puis je synchronize la mise à jour de la ListBox...mais généralement ma ListBox et en OwnerDrawVirtual, ou au minimum Virtual...du coup pas besoin d'affecter ses items, il suffit de définir son Count et de définir l'évènement OnData ou OnDrawItem

    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
     
    Task := TTask.Create(
       procedure
       begin
     
         s := IdHTTP1.Get('requête_php');
     
         var  JSon  := TJSonObject.ParseJSONValue(s);
         var L := TStringList.Create;
             for I := 0 to TJSONArray(JSon).Count-1 do
             begin
     
    		 // récupération des données
     
               TJSONArray(JSon)[i].TryGetValue<string>('id_commande', id_commande);
     
    		  // ajout dans listbox
     
               L.(id_commande);
     
             end;
     
     
         TThread.Synchronize(TThread.Current,
           procedure
           begin
     
              FList.Free; // FList est une TStringList, membre de Form1
              FList := L; // je lui donne ma nouvelle liste (qu'il ne faut donc pas détruire ici)
              ListBox1.Count := L.Count; // mise à jour du Coun
              ListBox1.Invalidate; // nécessaire si le Count n'a pas changé
           end);
     
       end);
       aTask.Start;
    ...
     
    procedure TForm1.ListBox1Data(Control: TWinControl; Index: Integer;
      var Data: string);
    begin
      Data = FList[Index]; // correspondance entre ListBox1 et FList
    end;
    si tu ne veux pas de ListBox virtuelle, tu peux aussi faire

    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
     
    Task := TTask.Create(
       procedure
       begin
     
         s := IdHTTP1.Get('requête_php');
     
         var  JSon  := TJSonObject.ParseJSONValue(s);
         var L := TStringList.Create;
        try
             for I := 0 to TJSONArray(JSon).Count-1 do
             begin
     
    		 // récupération des données
     
               TJSONArray(JSon)[i].TryGetValue<string>('id_commande', id_commande);
     
    		  // ajout dans listbox
     
               L.(id_commande);
     
             end;
     
     
         TThread.Synchronize(TThread.Current,
           procedure
           begin
               ListBox1.Items.Assign(L);
           end);
         finally 
               L.Free;
         end;
       end);
       aTask.Start;
    ...
    Developpez.com: Mes articles, forum FlashPascal
    Entreprise: Execute SARL
    Le Store Excute Store

  4. #4
    Débutant
    Profil pro
    Inscrit en
    juillet 2003
    Messages
    878
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : juillet 2003
    Messages : 878
    Points : 323
    Points
    323
    Par défaut
    @gbegreg super ça fonctionne, merci !
    il faut dire qu'avec l'habitude de D7, j'avais oublié ces petites choses

    @Paul TOTH merci également
    maintenant, c'est propre au Tlistbox, si je dois afficher ces données sur d'autres compo visuelles, que devrais je faire ?

  5. #5
    Membre émérite Avatar de pprem
    Homme Profil pro
    MVP Embarcadero - formateur&développeur Delphi, PHP et JS
    Inscrit en
    juin 2013
    Messages
    1 475
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Loiret (Centre)

    Informations professionnelles :
    Activité : MVP Embarcadero - formateur&développeur Delphi, PHP et JS
    Secteur : Enseignement

    Informations forums :
    Inscription : juin 2013
    Messages : 1 475
    Points : 2 812
    Points
    2 812
    Par défaut
    Citation Envoyé par Coussati Voir le message
    @Paul TOTH merci également
    maintenant, c'est propre au Tlistbox, si je dois afficher ces données sur d'autres compo visuelles, que devrais je faire ?
    Si le JSON est volumineux, le stocker dans une table en mémoire ou un autre format de données qui pourrait être exploité par les composants qui en auront besoin.

    Si le JSON ne l'est pas, le stocker tel quel et le parcourir lorsqu'on a besoin de le traiter.

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

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

    Informations forums :
    Inscription : novembre 2002
    Messages : 8 510
    Points : 27 558
    Points
    27 558
    Par défaut
    Citation Envoyé par Coussati Voir le message
    @gbegreg super ça fonctionne, merci !
    il faut dire qu'avec l'habitude de D7, j'avais oublié ces petites choses

    @Paul TOTH merci également
    maintenant, c'est propre au Tlistbox, si je dois afficher ces données sur d'autres compo visuelles, que devrais je faire ?
    tout dépend du composant...mais en réalité une listbox virtuelle permet d'afficher un peu n'importe quoi avec un peu de code
    Developpez.com: Mes articles, forum FlashPascal
    Entreprise: Execute SARL
    Le Store Excute Store

Discussions similaires

  1. Progressbar dans un traitement long
    Par Duan dans le forum Débuter
    Réponses: 11
    Dernier message: 17/07/2011, 05h03
  2. Traitement dans Servlet problème dans jsp après forward
    Par mattrixx dans le forum Servlets/JSP
    Réponses: 3
    Dernier message: 21/04/2011, 13h14
  3. Réponses: 3
    Dernier message: 22/08/2007, 16h53
  4. Réponses: 5
    Dernier message: 20/10/2006, 15h26
  5. Fermeture avec traitement long dans le onActivate
    Par benj63 dans le forum C++Builder
    Réponses: 14
    Dernier message: 20/03/2006, 18h54

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