IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

API, COM et SDKs Delphi Discussion :

Application.processmessage - durée d'execution ?


Sujet :

API, COM et SDKs Delphi

  1. #1
    Membre éclairé
    Profil pro
    Inscrit en
    Mai 2002
    Messages
    251
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2002
    Messages : 251
    Par défaut Application.processmessage - durée d'execution ?
    Salut à tous, j'utilise comme pas mal de monde le

    Application.processmessage;

    pour que Windows affiche ma progressbar pendant un labs de tps +/- bloqué dans une boucle.

    J'ai une grosse boucle dans laquelle, je fais a chaque debut de boucle (au préhalable, j'ai paramétré ma variable interval avec une valeur fixe, idem pour le attente qui prend avant la boucle la valeur du gettickcount !) :

    while ((attente + interval) > gettickcount) do application.ProcessMessages;
    attente := gettickcount;

    le but est de remplacer le TTimer pour compter mes ms dans un programme, ce TTimer n'est pas du tout précis. Question : Application.processmessage est-il succeptible de bloquer mon application lors de son appel ? Si oui combien de temps ? J'ai pas vraiment de grosse gestion d'interface utilisateur, j'ai un progressbar qui doit être rafraichi, quelque Tlabel et un petit graphique de 300x500px dans lequel je dessine une courbe dans le Canvas.

    Je ne sais pas si j'ai tout compris du application.ProcessMessages mais pour moi il est evident que son appel va prendre un peu de temps et qu'il va forcement executer quelques petite chose qui prendrons quelques ns ou même ms ?

    Merci d'avance pour votre lumiére !

  2. #2
    Membre Expert

    Profil pro
    Inscrit en
    Novembre 2007
    Messages
    1 519
    Détails du profil
    Informations personnelles :
    Âge : 41
    Localisation : France

    Informations forums :
    Inscription : Novembre 2007
    Messages : 1 519
    Billets dans le blog
    1
    Par défaut
    Que fais Application.processmessage ? Et bien comme son nom l'indique il sert à traiter les messages en attente. Mais quels messages ? Pour ça il faut comprendre le mécanisme de Windows pour la gestion de des fenêtres.

    L'interaction entre les divers fenêtres et processus se fait via ce système asynchrone de message. Lorsque tu cliques sur un bouton avec la souris, il n'y a pas interruption du code en cours en disant "hop hop hop moi la souris j'ai cliquée sur le bouton", il y a mise en queue d'un message indiquant qu'il vient d'y avoir un clic de bouton. Et lorsque l'application ne fait rien elle traite ses messages ce qui provoque divers comportement comme le redessinement de la fenêtre, déclenchement des évènements.

    Lorsque tu fais une boucle "100% CPU" le programme ne fait jamais rien, donc ne traite jamais ses messages, c'est pourquoi l'interface visuelle "freeze" car le dessin n'est pas accomplit. D'où un appel explicite du traitement des messages via un Application.processmessage.

    Alors maintenant pour répondre à ta question, tu dois bien te rendre compte que, bien sûr, un appel à Application.processmessage va te consommer du temps, ce temps que tu n'allouais pas dans ta "boucle 100%" mais il est difficile de comptabiliser combien de temps, je dirais que ça dépends du nombre de message et de combien chaque message prends de temps à être traité.

    Néanmoins tu peux faire une moyenne en comparant des prises de temps sans et avec Application.processmessage.

  3. #3
    Membre Expert Avatar de philnext
    Profil pro
    Inscrit en
    Octobre 2002
    Messages
    1 553
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2002
    Messages : 1 553
    Par défaut
    Un copier collé issu de l'excellent F Piette :
    http://www.overbyte.be/frame_index.h...ducts/ics.html

    Application.ProcessMessages is something people like to call often, but what is it, what are the benefits and what are the disadvantages

    What is it?
    It calls the message pump, which handles incomming Windows messages until there is no more messages in the message queue. Normally it is bad practice to call it directly, unless you are sure you know what you are doing, since Delphi already calls the message pump already while your application is idle.

    What are the benefits of calling it?
    To be honest... None. If your application is written right, you will never ever have to call it directly. If you really need to call it, you might want to re-evaluate the desing of your application.

    But why do people like to call Application.ProcessMessage, if it is so bad?
    Well, if your application does not respond when you want it, it is very easy to just call it. It is generally wrong because Delphi does all that for you. People often call it to update the display of some control component, i.e. a Label. But in such cases you are better off calling the Update method of the control itself, which will send (not Post) a message to the window of the control itself and cause the control to be updated immediatly. Almost all control components have an update method, i.e. Label.Update. Also, many people believe they have to pause their application using wait loops while some event happens because they dont understand Windows programming. Then they feel it necessary to insert a call to the message pump in the wait loop or their application will freeze while waiting. This is generally unnecessary and wastes lots of CPU time. In these cases it is best to re-evaluate the design of the application and rewrite it if necessary to take advantage of the event-driven nature of Windows programming.

    What are the disvantages?
    A lot! For example if you call Application.ProcessMessages from within an event of a component, and if that component generates its events from within the message pump, then you are in deep trouble. In fact, you are calling yourself at that moment. I have made a simple example of what can happen with a simple timer. You can download it at: http://www.mestdagh.biz/ics/demos/ReEnterTest.zip

    As an example, suppose you call the message pump in the OnReceive event of an ICS component. From there you call a Receive method to receive the data. But your code is badly written and slow, so you decide to call Application.ProcessMessages, and if at that time already new data is received by WinSock, your OnReceive handler will be called again before it ends. When the second instance of your OnReceive finishes, the next line of the first instance will continue. You can then imagine what can happen... Corrupted, lost or duplicated data; infinite loop and all sorts of Bad Things.

    This is not a component issue, it is the way Windows was design. Before you call the message pump you must learn how the Windows messaging system works, and how messages are transformed to events.

    Note that a modal form is calling the message pump also (because it is idle and just waiting for messages, eg a mouse click), meaning that if you display for example a dialog box, then you are indirect calling the message pump, doing the same thing.

  4. #4
    Membre Expert

    Profil pro
    Leader Technique
    Inscrit en
    Juin 2005
    Messages
    1 756
    Détails du profil
    Informations personnelles :
    Âge : 47
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Leader Technique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juin 2005
    Messages : 1 756
    Par défaut
    Evidemment, Application.ProcessMessages ne va pas être instantané.
    Maintenant on ne peut pas prédire sa durée.

    le but est de remplacer le TTimer pour compter mes ms dans un programme, ce TTimer n'est pas du tout précis.
    Le TTimer est fait pour déclencher un événement a interval de temps régulier. Il permet ainsi d'effectuer un certain traitement régulièrement, ou encore de retarder un traitement (par exemple, lancer une recherche incrémentale lorsque l'utilisateur arrête de tapper au clavier...).
    Par contre, il n'est pas du tout fait pour faire un chronomètre.

    Si tel est ton besoin, il faut plutôt lire la date (sur une horloge suffisament précise) au début du traitement, lire la date à la fin du traitement, puis faire la différence pour connaitre la durée écoulée.

    Tu peux le faire avec GetTickCount, mais il faut bien avoir concience que même si cette fonction renvoie une durée en ms, sa résolution n'est pas d'une milliseconde, mais plutôt 15 ou 20 (je ne sais plus exactement). Disons 20 ms.
    Ca veut dire que chaque fois que tu lis une date, tu as une incertitude de 20 ms sur la date lue.
    Au final, tu te retrouve donc avec une incertitude absolue de 40 ms sur la durée que tu vas mesurer.

    Si tu as besoin d'une horloge plus précise, il faut plutôt utiliser les compteurs de performance (QueryPerformanceCounter). Ces derniers possède une incertitude absolue de 100 ns sur chaque mesure. On peut ainsi pratiquement mesurer le temps écoulé entre deux lignes de code.

  5. #5
    Membre éclairé
    Profil pro
    Inscrit en
    Mai 2002
    Messages
    251
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2002
    Messages : 251
    Par défaut
    j'adore vos réponses, précises ... parfaite !
    merci pour vos lumières, je vais faire des tests

  6. #6
    Membre éclairé
    Profil pro
    Inscrit en
    Mai 2002
    Messages
    251
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2002
    Messages : 251
    Par défaut
    j'ai réalisé une phase de 3 secondes d'application.processmessage avant de lancer mes boucles où le tps est un élément important ! mais à relire le texte en anglais, j'ai plutot interet si j'ai bien compris de réaliser l'update des composants (pendant mes phases de boucle ou je dois raffraichir les données écran) qui m'interesse uniquement pour éviter tout attente non maitrisée, non ?

    Label.Update
    image.Update
    progressbar.Update ...

    -> seulement ces composant pour eviter que ça bloque à un moment donné, pouvez-vous confirmer ?

    Merci pour votre aide

  7. #7
    Membre éclairé
    Profil pro
    Inscrit en
    Mai 2002
    Messages
    251
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2002
    Messages : 251
    Par défaut
    Pour le moment ça semble marcher impeccable, je vous remercie tous pour votre aide !

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Réponses: 0
    Dernier message: 05/08/2009, 09h47
  2. [VB.NET] Combobox, Datasource et durée d'execution
    Par lacsap49 dans le forum Windows Forms
    Réponses: 1
    Dernier message: 19/05/2006, 16h06
  3. Réponses: 2
    Dernier message: 27/09/2005, 16h32
  4. problème avec Application->ProcessMessages()
    Par petitours dans le forum C++Builder
    Réponses: 4
    Dernier message: 15/08/2005, 10h27
  5. [langage] durée d'execution d'un pgme...
    Par perlgirl dans le forum Langage
    Réponses: 4
    Dernier message: 15/11/2004, 11h35

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo