Attendre la fin d'un thread créé par CreateThread() - Delphi/Pascal - Programmation
Marsh Posté le 09-09-2005 à 00:47:45
Bon finalement j'ai trouvé une solution qui fonctionne mais par contre je sais pas si "c'est bien" de faire comme ça ^^ :
Code :
|
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
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 :
--------------------------- |
Et je ne sais pas quoi changer/corriger pour éviter ce bug
Qu'est-ce qui ne va pas ?
Marsh Posté le 09-09-2005 à 09:56:36
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).
Marsh Posté le 09-09-2005 à 12:39:17
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.
Marsh Posté le 09-09-2005 à 16:48:03
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).
Marsh Posté le 09-09-2005 à 18:33:43
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.
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
Marsh Posté le 16-10-2005 à 01:49:46
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
Marsh Posté le 17-10-2005 à 09:33:45
pd l'exec du thread, les traitements qui se font via la vcl (affichage, etc) doivent se faire via la methode synchonize du thread...
Marsh Posté le 17-10-2005 à 11:55:54
To Copy il devrait commencer à 1 plutôt qu'à 0, non ?
Inekman a écrit : |
Et cette fenêtre principale, tu la caches avant de démarrer le thread ? Tu veux dire quoi par "ne revient pas" ?
Marsh Posté le 08-09-2005 à 17:23:51
Yop, voilà ce que j'ai codé à ce jour :
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 :
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