begin process at 2012 02 11 15:19:16
  Trouver un code source :
 
dans
 
Accueil > Forum > 

Delphi

 > 

Système

 > 

Autre

 > 

utilisation des threads avec des progressbar, tlabel et showmessage


Derniers messages déposésPoser une question dans le forum ou lancer une discussion

utilisation des threads avec des progressbar, tlabel et showmessage

jeudi 26 juin 2008 à 12:57:43 | utilisation des threads avec des progressbar, tlabel et showmessage

mimimou

bonjour a tous,
je viens de me farcir quasiment tout les tutos concernant les thread, mais je n ai visiblement pas trouve la bonne solution, voila mon soucis :
J ai une fiche qui comporte un TLabel, un progressbar et un TTimer. le ttimer gere le progressbar qui , une fois arrive a 100%, verifie la presence d un fichier " hostX.ini ". Si ce fichier existe :
- le ttimer se met en pause
- le tlabel.caption change 
- un composant style "showmessage + progressbar" apparait pour informer que le fichier est en cours de transfert.
- le fichier .ini est envoye au client grace a un composant ICS. Ce dernier le recoit et le traite, le modifie, et le renvoie au serveur.
- le pseudo-showmessage se ferme.
- le progress bar se remet en route quand le .ini est receptionne, et le tlabel.caption rechange.

Donc tout ceci prend un certain temps, mais le truc c est que toute l application est figee pendant cette duree, le tlabel ne change pas, le showmessage apparait mais le plus souvent tout blanc, et sans la bar de progression qui s y trouve, etc...

J ai bien compris qu il faut pour tout ca utiliser les thread, mais les exemples que j ai pu trouver ne fonctionnent pas, ou plutot ne correspondent pas vraiment a ce que je cherche.
Si quelqu un a une idee, n hesitez pas et je vous donnerais peut etre plus de details sur certains bouts de code.
J ajoute aussi que mon soft a une 15zaine de fiches differentes, et que l envoie du fichier .ini implique l appel de bouts de codes dans plusieurs fiches, je ne peux donc absolument pas mettre tout le code de traitement et d envoie dans mon thread (enfin j espere ne pas avoir a en arriver la!)
Merci a tous en tout cas, ciaooo

miMim
jeudi 26 juin 2008 à 13:07:48 | Re : utilisation des threads avec des progressbar, tlabel et showmessage

l0sth34d2

Pour ce qui est du problème de l'application qui fige.. tu doit faire passer la procedure Application.ProcessMessages pendant la progression.
jeudi 26 juin 2008 à 13:16:19 | Re : utilisation des threads avec des progressbar, tlabel et showmessage

mimimou

heu, j ai lu un peu partout qu il etait fortement deconseille d utiliser cette commande afin d eviter les crash ou je ne sais trop quoi, mais plutot utiliser les thread a la place.

En tout cas merci pour ta rapidite , je viens de poster ya 15mn :)

 

jeudi 26 juin 2008 à 13:20:25 | Re : utilisation des threads avec des progressbar, tlabel et showmessage

l0sth34d2

Pas de problème.

Si tu utilise Application.ProcessMessage un peu partout, ton application risque fort bien de crasher effectivement. Cette procedure permet à l'application de passer à la prochaine action, de faire un repaint, de minimizer, maximizer, etc.. durant une très grosse action. Utiliser cette procedure dans un evenement OnProgress (par exemple) sera sécuritaire et permettera à ta fiche de se rafraichir constamment durant la progression.
jeudi 26 juin 2008 à 18:12:18 | Re : utilisation des threads avec des progressbar, tlabel et showmessage

mimimou

arghh, le probleme c est que je ne vois pas ou je peux inserer cette fonction, car a partir du moment ou le fichier .ini se trouve dans le repertoire, il se passe plusieurs evenements, le showmessage avec sa barre de progression qui boucle tant que le fichier n est pas revenu du client, un envoie du fichier en sendStr(), et tout ce ci dans des fiches differentes... c est un peu complique a expliquer simplement car le soft est assez complexe, et ca serait laborieux et difficile d expliquer le cheminement.
En fait, tout ce que je souhaite, c est de pouvoir eviter par n importe quel moyen le freeze, ou les problemes de rafraichissement des fenetres, tlabel et autre barprogress de mon application.
Aussi ajouter que tout ceci ne se passe pas sur la fiche principale, ,mais sur une fiche ouverte en ShowModal.
jeudi 26 juin 2008 à 19:23:01 | Re : utilisation des threads avec des progressbar, tlabel et showmessage

florenth

Membre Club
Salut,

Je vois que tu n'as pas choisi le programme le plus simple pour commencer à utiliser des threads !

En tout cas, l'idée c'est de faire faire le traitement dans ton thread séparé (procédure Execute tu TThread) et l'affichage dans le thread principal (celui où tu es par défaut).

Pour cela, il va falloir que tu déplaces tout le code qui attend, puis récupère ton message, le modifie et le renvoie dans la procédure Execute et appeler une procédure de synchronisation pour mettre à jour l'affichage.

Par exemple, si ton Thread s'apelle TMyThread, tu auras:

unit UnitThread;

interface

uses
  Classes;

type
  TMyThread = class(TThread)
  private
    FStatus: Integer;     // on dira que 0=RAS - 1=erreur
    FProgress: Integer;   // Avancement en pourcentage.
    FMsg: string;         // Message à donner.
    FEvent: TNotifyEvent; // Evènement de progression à appeler régulièrement
    procedure AttenteMessage;
    procedure RecupereMessage;
    procedure ModifieMessage;
    procedure RenvoitMessage;
  protected
    procedure Execute; override;
    procedure DoProgress;
  public
    property Progress: Integer read FProgress;
    property Msg: string read FMsg;
    property OnProgress: TNotifyEvent read FEvent write FEvent;
  end;

var
  MyThread: TMyThread;

implementation

procedure TMyThread.Execute;
begin
  {>> Exécute les actions les unes à la suite des autres }
  FStatus := 0;
  AttenteMessage;
  if FStatus = 0 then
    RecupereMessage;
  if FStatus = 0 then
    ModifieMessage;
  if FStatus = 0 then
    RenvoitMessage;

  {>> Indique que tout est fini }
  FProgress := 100;
  FMsg := 'Tout est fini';
  Synchronize(DoProgress);
end;

procedure TMyThread.DoProgress;
begin
  if Assigned(FEvent) then
    FEVent(Self);
end;

procedure TMyThread.AttenteMessage;
begin
  FMsg := 'Attente de réception du message';
  FProgress := 0;
  while not Terminated do
  begin
    // attente ici.
    // Synchronize(DoProgress); a appeler de temps en temps comme Application.ProcessMessages
  end;
end;

procedure TMyThread.RecupereMessage;
begin
  FMsg := 'Réception du message';
  FProgress := 25;
  // récupération ici
   // Synchronize(DoProgress); a appeler de temps en temps
end;

procedure TMyThread.ModifieMessage;
begin
  FMsg := 'Modification du message';
  FProgress := 50;
  // modification ici
   // Synchronize(DoProgress); a appeler de temps en temps
end;

procedure TMyThread.RenvoitMessage;
begin
  FMsg := 'Renvoi du message';
  FProgress := 75;
  // envoi ici
  // Synchronize(DoProgress); a appeler de temps en temps
end;

end.


[copier-coller dans Delphi pour la colorisation]

Tu devrais déjà comprendre quelques trucs avec ça.

A utiliser comme suit :

uses
 
UnitThread;

[...]

MyThread := TMyThread.Create(True);
MyThread.FreeOnTerminate := True;
MyThread.OnProgress := MAJAffichage;
MyThread.Resume;


MAJAffichage étant une procédure dans ta fiche modale qui met à jor l'affichage bien entendu


Si quelque chose te bloque dnas ce code, dis le moi et je t'expliquerais.
Tu comprends bien que je ne peux pas tout t'expliquer en détails, c'est un peu long.

A+
Flo

Ressources Delphi, sources, tutoriaux, actu, ...: www.mx-dev.net [ Lien ]
vendredi 27 juin 2008 à 05:39:09 | Re : utilisation des threads avec des progressbar, tlabel et showmessage

mimimou

WOW!!! un grand merci a toi pour ton code et tes explications, je vais essayer d adapter tout ca dans mon appli, et te tiens au courant si j ai un soucis (ou si ca marche aussi bien entendu :)
a++
vendredi 27 juin 2008 à 07:38:33 | Re : utilisation des threads avec des progressbar, tlabel et showmessage

mimimou

bon, ben j ai des galeres, comme je pouvais l imaginer!! j ai pu avoir un rafraichissement du tlabel, mais apres ca update la fenetre bizarement et le thread ne s arrete pas.
Je viens de faire une version simplifie du code que j utilise, peut etre que ca te donnera une meilleure idee :

// cette fiche est ouverte en ShowModal
procedure TDispatcherStart.FormShow(Sender: TObject);
begin
  RenderFarmIndex       := 0;    // index des differentes pools a verifier
  ProgressBar.position  := 0;    // barre de progression
  TimerChecking.Enabled := true; // timer avec interval=60
end;

procedure TDispatcherStart.TimerCheckingTimer(Sender: TObject);
begin
  TitleLabel.caption   := 'Checking Pool '+RenderFarmName[RenderFarmIndex];
  ProgressBar.position := ProgressBar.position+1;

  if ProgressBar.position=100 then
    begin
    // verifie la presence du fichier 'Host_PoolName.ini'
    if FileExists(RenderFarmName[RenderFarmIndex]+'.ini') then
       begin
         TitleLabel.caption         := 'Updating Pool...';
         TimerChecking.Enabled      := false;   // mise en pause du timer le temps de traiter le fichier
         TransferToHost(scenename,id,hostname); // procedure de traitement (variables recuperees du fichier .ini)
       end;

    ProgressBar.position:=0;
    RenderFarmIndex:=RenderFarmIndex+1;
    if RenderFarmIndex>RenderFarmCount then RenderFarmIndex:=0;
    end;
end;

procedure TDispatcherStart.TransferToHost(scenename,id,hostname:string);
begin
  // a cet endroit du code, le TitleLabel.caption n a pas pu se rafraichir,
  // il est toujours affiche en 'Checking Pool '+RenderFarmName[RenderFarmIndex]

  AClient := TTcpSrvClient(OPServer1.Client[strToInt(id)]);
  AClient.SendStr(Host_PoolNameIni.Strings.Text);    // envoie du fichier Ini au client

  TransferDialog.Instruction := 'Transfer '+scenename+' to '+hostname;
  fileRcv := false;        // variable permettant de fermer ce ShowMessage si =true
  TransferDialog.Execute;  // Composant genre ShowMessage avec ProgressBar en boucle, le tps du traitement
                           // il a un evenement OnProgress ki permet de mettre a jour son progressBar
                           // et verifie aussi si fileRcv=true;
                           // Ceci me permet d attendre le retour du fichier modifie par le client
                          // mais le message n apparait pas et le progressbar non plus

  // une fois le fichier modifie recupere du client par la procedure suivante, on peut remettre le timer en route
  TimerChecking.Enabled := true;
end;


procedure OPServerOnClientDataAvailable(Sender : TObject; Error  : Word);
begin
  // recuperation du fichier .ini par le client
  with Sender as TTcpSrvClient do
    begin
    RcvdLine               := ReceiveStr;
    OPServer.IniLines.Text := RcvdLine;
    end;
  OPServer.IniLines.saveToFile(RenderFarmName[RenderFarmIndex]+'.ini');

  fileRcv := true; // fermeture du TransferDialog
end;


Voila j ai essaye de simplifier au maximum le code, car en realite il est un peu plus complexe que ca.
Mais c est une bonne base pour me dire a quel endroit je peux inserer la creation du thread et quelles fonctions
je dois mettre en .Execute
J espere ne pas prendre trop de ton temps, mais je te remercie encore mille fois pour ton aide :)
a+

miMim

vendredi 27 juin 2008 à 10:17:54 | Re : utilisation des threads avec des progressbar, tlabel et showmessage

florenth

Membre Club
Ah ouais, c'est normal que ça marche pas !

Tu mélanges dans ton code le traitement et l'affichage.
Or, c'est justement cela qu'il faut séparer.

A partir de ton code, je peux te donner quelques points de départ:

I- Tu crées une procédure nommée MAJAffichage dans ton TDispatcherStart qui doit ressembler à ça (pour le moment, ne cherche pas à avoir exactement les mêmes infos dans ta fiche d'attente, tu ajouteras le reste par la suite, il faut pour le moment faire fonctionner le "gros")

procedure TDispatcherStart.MAJAffichage(Sender: TObject);
begin
  TitleLabel.Caption := MyThread.Msg;
  ProgressBar.Position := MyThread.Progress;
end;


II- Tu déplaces tout ceci dans les bonnes méthodes du thread:

RenderFarmIndex       := 0
[...]
  if FileExists(RenderFarmName[RenderFarmIndex]+'.ini') then
       begin
         TitleLabel.caption         := 'Updating Pool...';
         TimerChecking.Enabled      := false; 
         TransferToHost(scenename,id,hostname);
       end;
[...]
procedure TDispatcherStart.TransferToHost(scenename,id,hostname:string);


III- Je ne comprends pas pourquoi tu as ça: "ProgressBar.position := ProgressBar.position+1"
C'est toi qui décides d'avancer ta ProgressBar ? C'est pas logique du tout et je ne comprends plus trop ton code.

IV- Du coup, je te conseille de faire un programme-test utilisant les threads car je ne suis pas sûr que tu aies tout compris.
Tu peux regarder mon programme ici : http://www.delphifr.com/codes/MISE-JOUR-APPLICATION-ASSISTANT-SIMPLE-RAPIDE_42534.aspx
Si ça peut t'inspirer...

Ressources Delphi, sources, tutoriaux, actu, ...: www.mx-dev.net [ Lien ]
vendredi 27 juin 2008 à 12:21:44 | Re : utilisation des threads avec des progressbar, tlabel et showmessage

mimimou

C clair que je suis loin d avoir tout compris aux Thread, mais ca commence a rentrer... 
Donc pour la progressBar, c volontaire, car je dois laisser environ 5 secondes d interval entre la verification des pools. Cette progressBar est juste "visuelle" pour ne pas laisser l appli sans rien faire pendant 5 secondes. 
Par contre, apres mon dernier post, j ai essaye un truc : J ai creer un autre progressbar ki tourne en boucle, et que j ai mis dans un Thread en me basant sur ton code (ca fonctionne nikel). Dans le FormShow, j ai mis les lignes pour creer le thread et le demarrer. Donc des que la fenetre s ouvre, je vois bien mon 2eme progressbar ki tourne en boucle dans son nouveau thread.
Le soucis, c est qu il se fige sitot que la procedure  OPServerOnClientDataAvailable est appelee. (cette procedure intervient quand le client renvoie le fichier .ini au serveur). Je pige pas car cette procedure se trouve dans une fiche de la form principale, et par consequent sur le thread principal. Cette procedure est assez longue a traiter, et donc le progressbar se fige tant que la procedure n est pas finie. Et ce que je comprend encore moins, c est que j ai mis volontairement un Label.caption:='toto'; en toute 1ere ligne de cette procedure, ce qui voudrait dire qu au moment ou elle est executee, le label devrait passer en 'toto', ben non, il passe en 'toto' une fois la procedure terminee :(
Ca me depasse un peu la programmation parfois mais bon je ne me decourage pas, et j te remerci encore pour tes infos, j ai mis a jour mon code avec ton nouveau post, mais j ai toujours le meme pbm... je vais jeter un coup d oeil a ton soft... a+ tard

1 2

Cette discussion est classée dans : fichier, ini, tlabel, progressbar, showmessage


Répondre à ce message

Sujets en rapport avec ce message

fichier .ini surchargé ?? [ par finipe ] Bonjour à tous. J'ai réalisé un petit prog utilisant des fichiers .ini pour conserver des infos. Tout fonctionne très bien, sauf depuis hier, alors qu Protection des applications et utilisation du registre au lieu d'un fichier INI [ par apz ] Salut,Pour proteger mon appli. j'ai utilisé un fichier ini (Limite d'utilisation)le code pour ecrire :// var publique fEmplacement : string;Str0, Str Fichier ini [ par ak47 ] Salut!Je voudrais savoir si il est possible d'utiliser les .ini avec delphi (par exemple, si je fait une application et que je veux qu'elle aie un fic Pb de lecture d'1 fichier .ini [ par teefun ] Salut à tous Je suis moyen en programmation avec delphi, je m'en sortait jusqu'au moment ou il fallait sauvegarder les paramètres de mon application , lecture et écriture dans un fichier .ini [ par finipe ] Bonjour à tous !Je voudrais savoir comment faire pour : - écrire dans un .ini tous les items d'une listbox, de manière à pouvoir les récupérer en lisa fichier .ini [ par lanosic ] Bonjour, j'aimerais savoir comment enregistrer des donnée dans un fichier ini et comment les utiliser?Merci!Bonne journée a tous! Fichier ini [ par DonKillah ] Salut tout le monde, je suis un peu nouveau sur Delphi, avant je codais -enfin je code toujours- en C et en Asm ; donc j'ai une petite question ...Mon creer un fichier ini [ par snakefinger ] salut a tous ya t'il une commande en delphi pour creer un fichier ini.j'ai trouver le code dans visual basic mais je cherche en delphi .si quelq'un a fichier ini pour install QuickTime sur Win [ par didierauss ] Bonjour a tous,Je suis tous nouveau sur le site et avant toute chose je ne suis pas informaticien et je connais rien à la programmation, je suis graph Commentaire dans fichier ini [ par padsou ] Voila j'ai cherché de partout, dans l'aide de delphi, sur le net mais je n'ai pas trouvé comment mettre un commentaire dans un fichier ini. Comment pu


Nos sponsors


Sondage...

CalendriCode

Février 2012
LMMJVSD
  12345
6789101112
13141516171819
20212223242526
272829    

Consulter la suite du CalendriCode

Photothèque

 
Développement réalisé par Nicolas SOREL (Nix) avec l'aide de : Cyril DURAND et Emmanuel (EBArtSoft), Merci à Vincent pour ses précieux conseils.
CodeS-SourceS.com© Toute reproduction même partielle est interdite sauf accord écrit du Webmaster
CodeS-SourceS.com© est une marque déposée tous droits réservés

Google Coop CodeS-SourceS Google Coop CodeS-SourceS
Temps d'éxécution de la page : 1,170 sec (4)

Nous contacter | Annoncer sur CodeS-SourceS | Mentions légales