TGAUGE - POSSIBILITÉS GRAPHIQUES - PROGRESSION DANS UN THREAD

yvemoreau Messages postés 308 Date d'inscription mardi 11 juin 2002 Statut Membre Dernière intervention 26 septembre 2008 - 17 déc. 2003 à 02:37
japee Messages postés 1727 Date d'inscription vendredi 27 décembre 2002 Statut Modérateur Dernière intervention 6 novembre 2021 - 21 déc. 2003 à 01:01
Cette discussion concerne un article du site. Pour la consulter dans son contexte d'origine, cliquez sur le lien ci-dessous.

https://codes-sources.commentcamarche.net/source/18773-tgauge-possibilites-graphiques-progression-dans-un-thread

japee Messages postés 1727 Date d'inscription vendredi 27 décembre 2002 Statut Modérateur Dernière intervention 6 novembre 2021 8
21 déc. 2003 à 01:01
Merci sincèrement, yve, de t'être intéressé au problème.
Moi, je suis pour l'instant complètement désorienté. Ce n'est pas faute d'avoir essayé, mais là, je cale... :(
J'y reviendrai, forcément, mais là, j'ai d'autres choses à faire, en Delphi et ailleurs... ;)
Augmenter la priorité, ouais... mais enfin, ce qui me tourmente, c'est quand même qu'un Thread qui semble bien "ficelé" sous D4 ne le soit plus en compilant sous une autre version. Là, ça me perturbe vraiment, et comme j'ai d'autre sujets d'étude sur le feu...
Faudra que j'y revienne, c'est sûr, mais en attendant, je mets en "standby" (sinon je pète un cable ;)
Encore merci à toi, à + !
yvemoreau Messages postés 308 Date d'inscription mardi 11 juin 2002 Statut Membre Dernière intervention 26 septembre 2008
20 déc. 2003 à 17:26
rebonjour japee, après encore un peu d'étude ...

property OnTerminate: TNotifyEvent;
Description
Write an OnTerminate event handler to execute code after the thread finishes executing. The OnTerminate event handler is called in the context of the main VCL thread, which means VCL methods and properties can be called freely.

Donc si je comprends bien ,l'événenement OnTerminate est appelé par l'application ? Si oui alors on synchronise alors l'application avec elle même ? ce qui causerait le plantage ...

procedure TProgression.ThreadTerminate;
begin
EnCours := False;
LaPosition := 0;
{$IFDEF VER140 or HIGHER}//delphi 6 ou 7
AfficheProgression;
{$ELSE}
Synchronize(AfficheProgression);
{$ENDIF}
end;

A part ce petit bug ,le gauge ce comporte plutôt bien lors du déplacement de la fiche si on veut lui donner plus de chance faut augmenter la priorité de thread .nul besoin de le forcer à se redessiner maintenant ,pourquoi je ne sais pas !!! faut croire que la mise à jour aurait été fait avec delphi 6 ? qui intègre ses directive de compilation de le projet ...

Trouver l'erreur ? y'en a plus !!!!

peut-être fushia qui cause une erreur dans le premier comboList
Gauge1.ForeColor:=
StringToColor(ComboBox1.Items.Strings[ComboBox1.ItemIndex]);
mais là c'est ma faute !!!

En tout cas c'est très intéressant comme sujet !!!
yve
japee Messages postés 1727 Date d'inscription vendredi 27 décembre 2002 Statut Modérateur Dernière intervention 6 novembre 2021 8
19 déc. 2003 à 23:44
Bonsoir, yve, je vais creuser çà.
Mais pas ce soir... enfin à priori (on sait jamais).
Merci ;)
PS : n'empêche, ce n'est pas si simple, hein ? Halala...
yvemoreau Messages postés 308 Date d'inscription mardi 11 juin 2002 Statut Membre Dernière intervention 26 septembre 2008
19 déc. 2003 à 19:34
,
je constate aussi
Lors d'un exit; Terminate ne s'exécute pas !!! alors oui c'était correct lorsque l'on était dans la loop , alors il est faut de dire qu'il s'exécutait toujours 2 fois ...dsl

yve
yvemoreau Messages postés 308 Date d'inscription mardi 11 juin 2002 Statut Membre Dernière intervention 26 septembre 2008
19 déc. 2003 à 18:45
bonjour japee, j'ai fais quelques test et voici mes conclusions:

comme tu appel thread terminate dans btnStopClick ,il se produit une situation étrange ,(tu tourne toujours dans la boucle du thread ),si le NonStop est coché . pour l'expérience j'ai ajouter un boolean "existe" au niveau de l'unité question de vérifier ce qui se passe ,on se retrouve à appeler 2 fois Terminate puisqu'il s'appelle lui même seul automatiquement à la fin du thread...

procedure TProgression.Execute;
var i: Integer;
begin
existe:=true;
...
existe:=false;
end;

or dans btnStopClick tu appelle threadTerminate
comme tout arrête "existe" demeure à true donc execute ne se termine jamais (While existe=true do application.processMessages; pour vérifier dans OnTerminate)!!!

Or je règle la situation comme suit:
dans BtnStopClick
procedure TForm1.BtnStopClick(Sender: TObject);
begin
if EnCours then
begin
EnCours := False;
MaProgression.Priority:=tpTimeCritical;
end;
end;

Ce qui pousse le thread à sortir de sa loop et à terminer sa tache le plus vitte possible et Terminate s'exécute alors tel que supposé seul...

Mais dans terminate je ne comprends toujours pas pourquoi ^ca bloque or pour l'instant je me contente de faire ceci:

procedure TProgression.ThreadTerminate;
begin
LaPosition := 0;
AfficheProgression;
end;

ah oui j'oubliais

procedure TProgression.AfficheProgression;
begin
Form1.Gauge1.Progress := LaPosition;
Form1.Gauge1.Update;//force le redessin de la gauche maintenant
Form1.Label1.Caption := IntToStr(LaPosition);
end;



yve
japee Messages postés 1727 Date d'inscription vendredi 27 décembre 2002 Statut Modérateur Dernière intervention 6 novembre 2021 8
18 déc. 2003 à 16:03
Oulala, pfffff.... c'est un poil plus compliqué que ça.
En fait, le code peut être corrigé pour ne plus passer par
Synchronize(AfficheProgression)
dans la procedure TProgression.ThreadTerminate
et qui semble effectivement poser problème sous D6...(?)
Mais où j'ai un problème, c'est que, avec correction ou pas, compilé avec D6, le Thread ne se comporte plus comme doit se comporter un Thread convenable.
Si l'on déplace le Form pendant l'avancement du Thread, il stoppe son travail, ce qui n'est pas ce l'on serait en droit d'attendre de lui...
Bigre. Quelques nuits blanches en perspective sans doute...
La question troublante étant : pourquoi un code compilé sous D4 fonctionne-t'il sans problème apparent, alors que le même code compilé sous D6 ne fonctionne pas correctement ?
Sûr, c'est pas encore demain que je travaille pour la N.A.S.A., enfin vaut mieux pas (écroulé de rire) !
japee Messages postés 1727 Date d'inscription vendredi 27 décembre 2002 Statut Modérateur Dernière intervention 6 novembre 2021 8
18 déc. 2003 à 14:47
Exact, yve, compilé sous D6, je rencontre le même problème que toi !
Sous D4, c'est nickel...
Je vais essayer de comprendre où ça coince... Je prépare le doliprane ;)
yvemoreau Messages postés 308 Date d'inscription mardi 11 juin 2002 Statut Membre Dernière intervention 26 septembre 2008
18 déc. 2003 à 00:36
Salut, japee, j'ai oublié de mentionné où il se produit l'erreur ...
sans rien ne modifier au tutoriel...
-compile ...run .
-BtnStartClick .
-BtnStopClick(avant la fin du progress) .
-ohé ohé ohé ohé , ohé ici plus de réponse (Ctrl+alt+del)

j'ai de la difficulté à saisir que sous delphi 4 il ne se produit pas le même effêt que sous delphi 6...

yve
japee Messages postés 1727 Date d'inscription vendredi 27 décembre 2002 Statut Modérateur Dernière intervention 6 novembre 2021 8
17 déc. 2003 à 08:45
Bizarre, yve, chez moi il n'y a à priori aucun blocage du process.

Par contre, il faut corriger corriger le code ici

procedure TForm1.BtnPauseClick(Sender: TObject);
begin
if EnCours then
if not MaProgression.Suspended then // <- à ajouter
MaProgression.Suspend;
end;

En effet, en fonctionnement, autant de fois on cliquait sur Pause (déclenchant la procedure MaProgression.Suspend), autant de fois il fallait cliquer sur Start (procedure MaProgression.Resume) pour redémarrer!
(voir l'aide de Delphi à ce sujet)
yvemoreau Messages postés 308 Date d'inscription mardi 11 juin 2002 Statut Membre Dernière intervention 26 septembre 2008
17 déc. 2003 à 03:37
ouais ,c'est pas vraiment correct ! j'ai examiner plus a fond le problème ,et supprimer la procédure n'est pas la solution ,elle a sa raison d'être ,donc après examen le seul problème viens du Synchronize(); j'en conclu qu'on ne peut demander une synchronisation à un thread qui se termine !!!

procedure TProgression.ThreadTerminate; // Exécution avant destruction du thread
begin
EnCours := False;
LaPosition := 0;
AfficheProgression;
end;

mille pardons japee !!! si l'on pouvais supprimer nos commentaire,je vais tourner ma langue à l'avenir ...
yvemoreau Messages postés 308 Date d'inscription mardi 11 juin 2002 Statut Membre Dernière intervention 26 septembre 2008
17 déc. 2003 à 02:37
Hello japee


TProgression = class(TThread)
private
LaPosition: Integer;
procedure AfficheProgression;
protected
procedure Execute; override;
end;

...


procedure TProgression.Execute;
var i: Integer;
begin
FreeOnTerminate := True; // libère le Thread quand il est terminé
Priority := tpNormal;
repeat
for i := Form1.Gauge1.Progress to 100 do
begin
Sleep(20);
LaPosition := i;
Synchronize(AfficheProgression); // appel à la procedure d'affichage
if not EnCours then break;
end;
if not NonStop then Sleep(500); // pondération pour confort visuel
LaPosition := 0;
Synchronize(AfficheProgression); // appel à la procedure d'affichage
until not (NonStop) or not(EnCours);

LaPosition := 0;
Synchronize(AfficheProgression);
end;


procedure TForm1.BtnStopClick(Sender: TObject);
begin
if EnCours then EnCours:=false;// pour sortir de la boucle
end;

Le process bloquait , peut-être la procédure On terminate n'existait-elle déjà plus lors de son appel ?

enfin ça peut-être utile ,Bravo !!!!
yve