Pause qui libère le CPU? [Résolu] - Delphi/Pascal - Programmation
Marsh Posté le 03-11-2006 à 20:56:24
Citation : y a pas un moyen de faire plus simple? |
euh ... non ^^
Marsh Posté le 03-11-2006 à 23:23:18
Application.HandleMessage
Mais tant que l'application ne reçoit plus de messages, elle risque de ne pas repasser dans la boucle, donc c'est plutôt une solution quand on attend un évément de la part de l'utilisateur.
Sinon pourquoi n'utilises-tu pas Sleep ? Faire des pauses de quelques secondes (ou millisecondes si l'application doit réagir tout de suite) via Sleep allègera pas mal le CPU.
Voire même faire juste un Sleep de la durée requise, mais pendant le temps du Sleep l'application est bloquée.
Encore une autre solution : utiliser un TTimer, qui déclanche un événement après un nombre de secondes prédéfíni.
Marsh Posté le 04-11-2006 à 00:05:23
oua faut faire un choix
oui je connaissait sleep mais effectivement ça bloque un peu à la bourrin et comme c'est une appli où on peut faire pas mal de trucs (alors que cette boucle est en cours) ça serait dommage, c'est toujours bien mieux quand elle est réactive , au pire y a moyen d'utiliser les deux
je vais chercher du coté du TTimer, Application.HandleMessage risque de bugger car l'utilisateur utilisera prèsque toujours que cette boucle
Merci Antp
Marsh Posté le 04-11-2006 à 00:48:53
Flagad'aware a écrit : Application.HandleMessage risque de bugger car l'utilisateur utilisera prèsque toujours que cette boucle |
le seul risque avec HandleMessage c'est si l'application est réduite ou en arrière-plan (et encore, c'est à tester)
Marsh Posté le 05-11-2006 à 02:21:52
excuses-moi si je me suis mal exprimé mais justement c'est ça principale fonction de l'appli donc si bug pas bon c'est pour ça que je me suis permis de douter sans essayer
dans l'utilisation la plus courante, l'utilisateur ne fait rien d'autre qu'activer+arrière plan c'est pour ça
Marsh Posté le 05-11-2006 à 13:38:28
Pourquoi ne veut-tu pas regarder du coté des Thread ?
en Delphi c'est extremement simple et cela répond a ton besoin
Marsh Posté le 05-11-2006 à 20:21:41
bah ça me parrait plus simple comme ça , finalement avec HandleMessage ça a tourné plus de 5 heures avec l'appli minimisée dans la barre des taches et y en a eu des pauses.
faudrait oui que je me penche sur les threads, parceque ce que je fait c'est assez bourrin et effectivement les threads seraient bien plus appropriés, la procédure que j'ai mis plus haut fait déja partie d'une boucle qui tourne tant que la caption d'un bouton est à manuel, le clic sur bouton fait passer de auto à manuel et inversement
Marsh Posté le 05-11-2006 à 22:45:30
Sinon le TTimer ça devrait être une bonne solution, c'est juste que tu dois penser ton code autrement (vu que t'as pas une boucle mais un événement).
Marsh Posté le 06-11-2006 à 23:14:47
oui je crois que je vais déja essayer ça, en fait, y a pas grand chose à changer du point de vue boucle/evenement, y a surtout à "deboucler" (si si c'est comme ça qu'on dit ) et le TTimer (re)lançera l'evenement avec le temps d'attente fixé par cette meme procedure, enfin je vois ça comme ça sans avoir essayé
par contre j'èspère qu'on peut facilement couper le timer?
mais galère les threads j'arrivai à rien déclarer
encore merci
Edit: ça marche nickel! et le CPU peut s'envoyer un Pulco dans son Hamac
je met ça si ça peut aider d'autre personnes dans mon cas, ça permet d'activer/désactiver le TTimer en cliquant sur un meme bouton:
procedure TMainForm.Button4Click(Sender: TObject); |
et le code périodiquement lancé dans:
procedure TMainForm.TimerTimer(Sender: TObject);
(evenement OnTimer)
Marsh Posté le 07-11-2006 à 00:17:12
le seul truc c'est qu'il faut toujours que l'interval soit assez grand pour lancer la procedure complète (TimerTimer) et au premier lancement il faut attendre que le temps de cet interval soit écoulé avant que ça décole
Marsh Posté le 07-11-2006 à 11:38:10
Ton Timer.Free me semble bizarre C'est pas plutôt Enabled := False que t'aurais dû mettre ? Et ton test est fait à l'envers on dirait (les commentaires collent pas avec le code )
Au passage, la comparaison sur le Caption du bouton c'est bien crado comme code j'aurais mis ça :
Code :
|
Tu peux toujours désactiver le Timer dans le début du OnTimer (TimerTimer), et le réactiver à la fin.
Pour le début, tu peux manuellement appeler la procédure TimerTimer dans le code.
Marsh Posté le 07-11-2006 à 20:08:08
lol oui j'ai une facheuse tendance à coder comme un goret
j'ai déja vu un code comme Timer.Enabled := not Timer.Enabled; dans le TComport (connect /deconnect) mais j'avait pas capté comment ça marchait exactement alors j'ai zappé, voila seulement que je comprend qu'en fait on applique à l'état du timer l'inverse de cet état qu'il soit actif ou pas
par contre non c'est pas inversé par rapport au commentaire enfin plutôt il est pas très clair... mais, pour l'appli, si la caption est à Manuel ça veut dire que la boucle est lancée et inversement , j'aurais du peut être commencer par if Button4.caption='Auto' then mais c'était pour couper la boucle que manuel était avant(heu si je me souviens bien)
effectivement pour Timer.Enabled := False ça permetra surement de pas planter avec "access violation" au bout de trois clics sur le bouton4 lol quoique le timer s'arrète bien
Marsh Posté le 07-11-2006 à 20:42:46
Évidemment qu'il s'arrête puisque tu le détruis Mais pour le remettre en route il va avoir du mal (ou alors ça va fonctionner très aléatoirement tant que la zone mémoire n'est pas réutilisée par autre chose...)
machin := not machin
ça veut dire que tu inverses son état. Comme un interrupteur quoi.
Puis ensuite tu mets à jour le caption en fonction du nouvel état.
Marsh Posté le 07-11-2006 à 20:59:30
ok lol, c'est pour ça que ça plantait en le réactivant...
par contre j'arrive pas à lancer manuellement TimerTimer
finalement j'ai fait ça:
Code :
|
et j'active le timer à la fin de TimerTimer juste après avoir paramétré l'interval
en fait j'ai jamais trouvé comment faire pour lancer manuellement, à chaque fois ça m'oblige à créer une procédure distincte et à l'appeler dans un buttonClick ou autre...
excuses-moi de te faire perdre ton temps avec mes questions de newbie
Marsh Posté le 08-11-2006 à 09:47:30
ou TimerTimer(Timer) pour faire comme si c'est le Timer qui l'avait déclanché (le paramètre c'est ce que tu reçois comme variable "Sender" pour savoir qui a appelé la procédure au cas où plusieurs composants sont reliés à la même procédure). Dans ton cas ça ne changera rien
Marsh Posté le 08-11-2006 à 19:36:54
ok je comprend mieux.
c pô toujours evident surtout quand on apprend comme ça à partir de prèsque rien, suis à la FAQ moi pas à la FAC
tourne nickel maintenant mon appli
Merci beaucoup pour ton aide
Marsh Posté le 03-11-2006 à 20:35:35
Salut à tous
y a déja un topic qui parle des pauses mais c'est différent
voila j'ai fait une procédure qui utilise Application.ProcessMessages; pour faire une pause avec un temps variable (de une minute voir moins à plus de deux heures) le problème c'est que ça utilise 50% du CPU sur un A64 X2 c'est ennuyeux...le but est que l'appli puisse tourner en tache de fond et meme sur un 'petit' PC genre Pentium 200Mhz
debut procedure.............
.....
Top := now;
stop:=false ;
repeat
if (now < top+((wait)/1000/3600/24)) then
begin
Application.ProcessMessages;
if Button4.caption='Auto' then stop:=true;
end
until (now = top+((wait)/1000/3600/24)) or stop;
end;
;
wait est en milisecondes, meme en retirant "if Button4.caption='Auto' then stop:=true;" (si y a pas ça c'est ctrl+alt+suppr pour sortir...)ça pompe du CPU au taquet!
je sais pas si ce genre de procédure est fait pour pas durer longtemps ou quoi, j'ai vu un tuto sur les threads mais ça me fait un peu peur : http://reisubar.developpez.com/threadevents/ y a pas un moyen de faire plus simple?
Message édité par Flagad'aware le 07-11-2006 à 00:24:36