Forum |  HardWare.fr | News | Articles | PC | S'identifier | S'inscrire | Shop Recherche
1708 connectés 

  FORUM HardWare.fr
  Programmation
  Delphi/Pascal

  Attendre la fin d'un thread créé par CreateThread()

 


 Mot :   Pseudo :  
 
Bas de page
Auteur Sujet :

Attendre la fin d'un thread créé par CreateThread()

n°1195277
Inekman
Posté le 08-09-2005 à 17:23:51  profilanswer
 

Yop, voilà ce que j'ai codé à ce jour :
 

Code :
  1. function TMaClasse.LancerProcessus: boolean;
  2. begin
  3.     temps.TempsDebut := now;
  4.     FfrmProcessing := TfrmProcessing.Create(nil);
  5.     FfrmProcessing.Show;
  6.     monThread.Th := CreateThread(nil, 0, @LeProcess, self, 0, monThread.Tid);
  7.     WaitForSingleObject(monThread.Th, INFINITE);
  8.     MessageBox(processHandle, 'fini', 'yes', 0);
  9.     Result := true;
  10. end;


 
Ensuite, dans LeProcess, j'appelle régulièrement une méthode MAJInformation(), laquelle mets à jour les informations concernant l'état d'avancement du processus dans la fenêtre FfrmProcessing. Cependant, lors de la première exécution de cette méthode, tout se bloque dès que je modifie une propriété d'un composant de la fenêtre créée :'(
 
Voilà un extrait de MAJInformation :

Code :
  1. procedure TMaClasse.MAJInformation;
  2. begin
  3.     with FfrmProcessing do
  4.         begin
  5.                bar1.position := (EffectueGlobal * 100) div TotalGlobal;
  6.                lblPourcentage.Caption := IntToStr(bar1.Position) + '%';
  7.                bar2.position := (EffectueCourant * 100) div TotalCourant;
  8.         end;
  9. end;


Quand la méthode est appelée dans LeProcess, tout se bloque à la ligne 5 de MAJInformation.
 
Cependant, tout fonctionne bien lorsque je n'utilise pas WaitForSingleObject mais dans ce cas, je ne sais pas comment savoir si ma fonction s'est terminée avec succès pour revenir enfin sur ma fiche principale.
 
Savez-vous à quoi est due cette erreur ?
 
Merci à vous :)


Message édité par Inekman le 08-09-2005 à 18:06:00
mood
Publicité
Posté le 08-09-2005 à 17:23:51  profilanswer
 

n°1195657
Inekman
Posté le 09-09-2005 à 00:47:45  profilanswer
 

Bon finalement j'ai trouvé une solution qui fonctionne mais par contre je sais pas si "c'est bien" de faire comme ça ^^ :
 

Code :
  1. LancerProcessus;
  2. repeat
  3.        Application.HandleMessage;
  4. until isThreadTerminated;


isThreadTerminated est un booleen initialisé à False au lancement de LancerProcessus et à la fin de l'exécution du thread, je passe cette variable à True. Et donc dès que c'est fini, ben je sors de la boucle et j'peux revenir à la fenêtre principale du programme.  
 
J'ai testé Application.ProcessMessage et HandleMessage, sans trop savoir qui fait quoi, et il s'avère que le 1er utilise 100 % du proc alors qu'avec HandleMessage c'est bon.
 
 
Maintenant j'ai un autre problème :D
 
Pendant l'exécution de la fonction du thread, lorsqu'on arrive à cette ligne :
 

NomCourt := Copy(Reglage.Source_chemin + Reglage.Source_fichier, 0, Length(Reglage.Source_chemin + Reglage.Source_fichier) - 8);


J'ai le message d'erreur suivant qui s'affiche :'( :

---------------------------
Debugger Exception Notification
---------------------------
Project Project1.exe raised exception class EOutOfMemory with message 'Out of memory'. Process stopped. Use Step or Run to continue.
---------------------------
OK   Help    
---------------------------


 
Et je ne sais pas quoi changer/corriger pour éviter ce bug [:airforceone]  
 
Qu'est-ce qui ne va pas ? :ange:

n°1195730
HelloWorld
Salut tout le monde!
Posté le 09-09-2005 à 09:56:36  profilanswer
 

Il fait quoi ton thread ? Si c'est copier un fichier, t'as une boite toute faite qui existe (celle utilisée par Windows, voir SHFileOperation).


---------------
FAQ fclc++ - FAQ C++ - C++ FAQ Lite
n°1195870
Inekman
Posté le 09-09-2005 à 12:39:17  profilanswer
 

Non non il ne copie pas de fichier, mais il fait un traitement dessus. Il récupère des données et les placent dans un autre fichier.

n°1196117
Zozol
Posté le 09-09-2005 à 16:48:03  profilanswer
 

Ta methode pour attendre la fin du thread me parait parfaite  
HandleMessage rend la main à l'application et revient sur ton code après qu'un message ai été traité. Ca peut attendre indéfiniment si ton programme n'a aucune raison de générer un message, mais autant que je sache, la fin d'un thread(à la sorite de la methode TThtread.Execute pour etre exact) en gènère un, donc pas de problème (Si j'ai dit une bêtise, puissent les Maîtres de ce forum me coriger).
 
Quant à ton exception, mystère. Je suppose que tu a essayé de décomposer (mettre (Reglage.Source_chemin + Reglage.Source_fichier)  dans une string avant la copy). Dans ce cas, ou cela plante-t-il?
 
Autre problème: Ton programme principale ne lance-t-il qu'un thread à la fois et ce thread ne lance-t-ils aucun thread à son tour? Because tu comprendra que quand 2 threads tentent d'acceder aux mème variables en mème temps, les choses se compliquent (c'est peu dire).


Message édité par Zozol le 09-09-2005 à 16:58:56
n°1196193
Inekman
Posté le 09-09-2005 à 18:33:43  profilanswer
 

Merci beaucoup pour ta participation zozol.
 
En ce qui concerne l'arrêt du thread, c'est la seule solution que j'ai trouvé. Sache que je n'utilise pas TThread pour mon objet. J'ai tout fait à l'aide de l'api Win32 (apprentissage inside). Normalement il faut utiliser WaitForSingleObject en lui donnant un timeout et elle renvoi un double mot à partir duquel on peut savoir si oui ou non le thread s'est arrêté etc mais chez moi cela bloque complètement le programme. Bref :)
 
Bon concernant le bug, j'ai trouvé finalement ^^. L'erreur venait au moment du lancement du thread auquel je transmet un pointeur comme paramètre. Sauf que là j'ai donné l'adresse du pointeur. Ceci explique cela. [:arg]
 
Bon ben tout marche pour le mieux pour l'instant. Je me demandais juste si la boucle avec le HandleMessage était bien, apparement oui ^^
 
Merci à tous ;)

n°1223891
Inekman
Posté le 16-10-2005 à 01:49:46  profilanswer
 

Je reviens à l'attaque à propos de ma fameuse boucle car ayant changé quelque peu mon code, cette astuce ne fonctionne plus :'(
 
La différence réside dans le fait que lorsque j'ai posté cette astuce à l'époque, la fenêtre TfrmProcessing était instanciée dans l'unité de ma fenêtre principale. Or depuis, j'ai décidé de créer cette fenêtre dynamiquement comme ça :
 
frmProcessing := TfrmProcessing.Create(nil);
frmProcessing.Show;
 
A la fin de l'exécution du thread, une méthode de la classe qui a créé cette fenêtre est exécutée :
 
CloseHandle(monThread.Th); // ferme le handle du thread
 
frmProcessing.Timer1.Enabled := false; // au cas où...
frmProcessing.Close; // j'utilisais .Release également
 
ThreadTerminated := true; // la fameuse variable qui est testée dans la boucle citée qq post plus haut
 
Ce qui est bizarre donc, c'est que le thread s'arrête, la fenêtre TfrmProcessing disparaît mais la fenêtre principale ne revient pas, aucun message ne semble lui être envoyé.
 
Je ne sais pas quoi faire :(

n°1224251
thierry-n
Posté le 17-10-2005 à 09:33:45  profilanswer
 


pd l'exec du thread, les traitements qui se font via la vcl (affichage, etc) doivent se faire via la methode synchonize du thread...

n°1224351
antp
Super Administrateur
Champion des excuses bidons
Posté le 17-10-2005 à 11:55:54  profilanswer
 

To Copy il devrait commencer à 1 plutôt qu'à 0, non ?
 
 

Inekman a écrit :


 
Ce qui est bizarre donc, c'est que le thread s'arrête, la fenêtre TfrmProcessing disparaît mais la fenêtre principale ne revient pas, aucun message ne semble lui être envoyé.


 
Et cette fenêtre principale, tu la caches avant de démarrer le thread ? Tu veux dire quoi par "ne revient pas" ?


---------------
mes programmes ·· les voitures dans les films ·· apprenez à écrire

Aller à :
Ajouter une réponse
  FORUM HardWare.fr
  Programmation
  Delphi/Pascal

  Attendre la fin d'un thread créé par CreateThread()

 

Sujets relatifs
probleme de menu contextuel crée avec dreamweaverSomme d'un nbre évolutif d'elmts &ref à une feuille cree ds la macro
VBA EXCEL. Faire attendre la fin d'une query pour continuer.[Pear::Spreadsheet] Fichier non créé
Crée un site webthread et timeout
Attendre qu'un prog soit fini pr passer à instruction suivanteDrag impossible sur un objet créé dynamiquement ?
Exécuter une méthode d'un objet dans un ThreadMulti-Thread
Plus de sujets relatifs à : Attendre la fin d'un thread créé par CreateThread()


Copyright © 1997-2022 Hardware.fr SARL (Signaler un contenu illicite / Données personnelles) / Groupe LDLC / Shop HFR