begin process at 2010 02 10 15:12:52
  Trouver un code source :
 
dans
 
Accueil > 

Code

 > 

Date & Heure

 > TUTO : TECHNIQUE POUR ATTENDRE

TUTO : TECHNIQUE POUR ATTENDRE


 Information sur la source

Note :
10 / 10 - par 1 personne
10,00 / 10

  • 1

  • 2

  • 3

  • 4

  • 5

  • 6

  • 7

  • 8

  • 9

  • 10
Catégorie :Date & Heure Classé sous :méthode, attendre, sleep, doevents, boucle Niveau :Débutant Date de création :13/03/2004 Date de mise à jour :13/03/2004 15:36:17 Vu :13 251

Auteur : jack

Ecrire un message privé
Site perso
Ce membre participe au partage de revenus publicitaires
Commentaire sur cette source (20)
Ajouter un commentaire et/ou une note


 Description

Simples recommendations pour faire des boucles d'attente.
Dans ces exemples, on va attendre 5 secondes, mais cela marche pour des valeurs beaucoup plus grandes (par contre pas utilisable en dessous de la seconde).

Technique 1 (avec bug possible) :
---------------------------------------
La technique consiste à utiliser l'instruction (pas l'objet) Timer.
Cette instruction renvoie le nombre de secondes écoulées depuis minuit.
Dim Debut As Long
Debut = Timer
Do While Timer - Debut < 5
DoEvents  ' Repasse la main au système en attendant
Loop

Cette technique a un gros inconvénient : à minuit, Timer repasse à zéro : Si vous faites votre boucle vers cette heure là, vous risquez d'attendre longtemps.

Technique 2 (sans bug) :
-----------------------------
Là, on va utiliser la date système pour faire l'attente :

Dim Debut As Date
Debut = Now  ' renvoie la date et l'heure courante
Do While Abs(DateDiff("s", MaDate, Now)) < 5
DoEvents  ' Repasse la main au système en attendant
Loop

Cette solution a le gros avantage d'être fiable, et de pouvoir attendre des durées quelconques : Il suffit re remplacer "s" (secondes) par une des autres unités de temps :
s  Secondes
n  Minutes (et pas m)
h  Heures
d  Jours
m  Mois
y  Années

Dernière précision :
----------------------
Les puriistes vous dirons que utiliser un DoEvents mange du temps machine; en effet, la boucle est exécutée quelques milliers de fois par secondes.
Certes (y cause bien, hein !), vous pouvez toujours la remplacer la l'API "Sleep" :
Vous mettez cette déclaration dans la partie Déclaration de votre feuille ou module
Declare Sub Sleep Lib "kernel32" Alias "Sleep" (ByVal dwMilliseconds As Long)
et vous remplacez les "DoEvents" par des "Sleep 1000" qui demandera au système d'attendre 1 seconde (1000 millisecondes) avant de poursuivre.

Vala. En espérant que ça puisse vous servir ...
Jack




 Sources du même auteur

Source avec Zip Source avec une capture SYSTRAY + BALLOON - VARIANTE AVEC TEXTE DANS L'ICÔNE
Source avec Zip Source avec une capture DATE-HEURE DE LANCEMENT D'UN PROGRAMME
Source avec Zip Source avec une capture SYSTRAY + BALLOON EN UN SEUL CONTRÔLE UTILISATEUR
Source avec Zip Source avec une capture Source .NET (Dotnet) SMS GENERATOR
Source avec Zip TRANSPORTER UNE DB ACCESS DANS UN DOCUMENT WORD

 Sources de la même categorie

Source avec Zip Source avec une capture Source .NET (Dotnet) FUSEAUX HORAIRES (HORLOGES ANALOGIQUES) par Blodox
Source avec Zip Source avec une capture ANNIVERSAIRE,FÊTES ET DICTONS par claude440
Source avec Zip Source avec une capture CALCULE HEURES DE NUIT 2 par ocejade
NUMÉRO DE SEMAINE par vb5zh
Source avec Zip HORLOGE À AIGUILLES (RADIAN) par brainbass

 Sources en rapport avec celle ci

Source avec Zip Source .NET (Dotnet) ATTENDRE LA FIN D'UN PROCESS EXTERNE AVANT DE FAIRE AUTRE CH... par royaltaz
Source avec Zip RÉCURSIVITÉ: PLACER HUIT REINES SUR UN ÉCHIQUIER par lucqum
Source .NET (Dotnet) EXÉCUTER UNE APPLICATION ET ATTENDRE OUI OU NON QU'ELLE SE T... par LandTech
Source .NET (Dotnet) ATTENDRE UN CERTAINS TEMPS (PAUSE) SANS "PERDRE LA MAIN" EN ... par hvb
ATTENDRE UN CERTAINS NOMBRE DE SECONDES/MILLISECONDES SANS "... par hvb

Commentaires et avis

Commentaire de Renfield le 13/03/2004 06:57:39 administrateur CS

Sleep semble en effet bien indiquée.....

(bonne idée de tuto...)

Commentaire de Afyn le 14/03/2004 09:53:23

Bien expliqué.
Un petit bout de code en exemple pourrait être bien venu
également

A+
Afyn

Commentaire de Afyn le 14/03/2004 09:56:31

Ha, oui ...
Si quelqu'un sait ce que fait réellement le DoEvents (décompilé
par exe ...) je serais curieux de savoir.

Re A+
Afyn

Commentaire de Xya le 14/03/2004 15:22:32

J'ai J'ai exécuté dans un débogueur un petit programme VB qui appelle DoEvents et voilà la procédure:

[MSVBVM60.rtcDoEvents]

73397BA3 &gt; 56               PUSH ESI
73397BA4   57               PUSH EDI
73397BA5   E8 33000000      CALL MSVBVM60.73397BDD
73397BAA   8BF0             MOV ESI,EAX
73397BAC   33FF             XOR EDI,EDI
73397BAE   83FE FF          CMP ESI,-1
73397BB1   0F84 10BA0100    JE MSVBVM60.733B35C7
73397BB7   393D 30034873    CMP DWORD PTR DS:[73480330],EDI
73397BBD   0F85 F8B90100    JNZ MSVBVM60.733B35BB
73397BC3   A1 38034873      MOV EAX,DWORD PTR DS:[73480338]
73397BC8   3BC7             CMP EAX,EDI
73397BCA   0F85 08BA0100    JNZ MSVBVM60.733B35D8
73397BD0   57               PUSH EDI
73397BD1   FF15 EC113773    CALL DWORD PTR DS:[&lt;&KERNEL32.Sleep&gt;]    ; kernel32.Sleep
73397BD7   66:8BC6          MOV AX,SI
73397BDA   5F               POP EDI
73397BDB   5E               POP ESI
73397BDC   C3               RETN

et quelques appels significatifs aux APIs en vrac:

733848DD   8B3D 28143773    MOV EDI,DWORD PTR DS:[&lt;&USER32.PeekMessageA&gt;]      ; USER32.PeekMessageA

7338494C   FF15 2C133773    CALL DWORD PTR DS:[&lt;&USER32.TranslateMessage&gt;]     ; USER32.TranslateMessage

73384956   FF15 30133773    CALL DWORD PTR DS:[&lt;&USER32.DispatchMessageA&gt;]     ; USER32.DispatchMessageA

73385BA2   FF15 28153773    CALL DWORD PTR DS:[&lt;&USER32.GetWindowLongA&gt;]       ; USER32.GetWindowLongA

73385BE6   8B3D 94143773    MOV EDI,DWORD PTR DS:[&lt;&USER32.SendMessageA&gt;]      ; USER32.SendMessageA

Le peu que j'en ai compris, c'est que DoEvents appellerait PeekMessage pour voir s'il y a des messages en attente pour la fenêtre, et s'il y en a les exécute (TranslateMessage, DispatchMessage). Sinon, il exécute Sleep.

Si quelqu'un maîtrisant l'assembleur et la prog Windows voudrait bien démêler ca, peut être qu'on avancerait un peu :)


Xya

Commentaire de Xya le 14/03/2004 15:30:51

Une autre précision: il semblerait que quand rtcDoEvents appelle Sleep, le paramètre passé soit toujours 0. D'après MSDN:

VOID Sleep(
  DWORD dwMilliseconds
);

dwMilliseconds
    [in] Minimum time interval for which execution is to be suspended, in milliseconds.

    A value of zero causes the thread to relinquish the remainder of its time slice to any other thread of equal priority that is ready to run. If there are no other threads of equal priority ready to run, the function returns immediately, and the thread continues execution.

Donc soit DoEvents s'occupe des messages en attente dans la file, soit s'il n'y en a pas arrête le thread en cours et laisse la main aux autres threads.


Xya

Commentaire de Renfield le 14/03/2004 15:54:55 administrateur CS

Xya a tout décris me semble-t'il du fonctionnement de DoEvents....

Commentaire de jack le 14/03/2004 18:24:43 administrateur CS

Et beh, j'en demandais pas tant ...
Ce qui me conforte dans l'utilisation de DoEvents qui n'est donc pas si maléfique que ça ...
A propos de ces appels aux APIs, il y a eu récemment une brave discution dans ce lien (auteur Unreal) : http://www.vbfrance.com/code.aspx?ID=20535

Commentaire de Renfield le 14/03/2004 20:39:00 administrateur CS

"maléfique" ?? il est même plus qu'utile parfois !!

evite par contre les

for i = 0 to 9999999
   doevents
   'action
next i

pour privilégier par exemple :

for i = 0 to 9999999
   if i mod 3000 = 0 then    doevents
   'action
next i

Commentaire de Xya le 15/03/2004 12:40:47

Si ça interesse qqun, voilà le code IL de LocalModalMessageLoop, qui est appellée par la version .NET de DoEvents:

Private Function LocalModalMessageLoop(ByVal form As Form) As Boolean

.maxstack 5
.locals (MSG V_0, Boolean V_1, Boolean V_2, Boolean V_3, Message V_4, Boolean V_5, Control V_6, Boolean V_7)
.try L_0000 to L_0114 catch Object L_0114 to L_011a
L_0000: ldloca.s V_0
L_0002: initobj MSG
L_0008: ldc.i4.0
L_0009: stloc.1
L_000a: ldc.i4.1
L_000b: stloc.2
L_000c: br L_0109
L_0011: ldloca.s V_0
L_0013: ldsfld NativeMethods.NullHandleRef
L_0018: ldc.i4.0
L_0019: ldc.i4.0
L_001a: ldc.i4.0
L_001b: call UnsafeNativeMethods.PeekMessage
L_0020: stloc.3
L_0021: ldloc.3
L_0022: brfalse L_00f6
L_0027: ldloc.2
L_0028: brfalse L_0109
L_002d: ldloca.s V_0
L_002f: ldfld MSG.hwnd
L_0034: ldsfld IntPtr.Zero
L_0039: call IntPtr.op_Inequality
L_003e: brfalse.s L_006b
L_0040: ldnull
L_0041: ldloca.s V_0
L_0043: ldfld MSG.hwnd
L_0048: newobj HandleRef..ctor
L_004d: call SafeNativeMethods.IsWindowUnicode
L_0052: brfalse.s L_006b
L_0054: ldc.i4.1
L_0055: stloc.1
L_0056: ldloca.s V_0
L_0058: ldsfld NativeMethods.NullHandleRef
L_005d: ldc.i4.0
L_005e: ldc.i4.0
L_005f: call UnsafeNativeMethods.GetMessageW
L_0064: brtrue.s L_0080
L_0066: br L_0109
L_006b: ldc.i4.0
L_006c: stloc.1
L_006d: ldloca.s V_0
L_006f: ldsfld NativeMethods.NullHandleRef
L_0074: ldc.i4.0
L_0075: ldc.i4.0
L_0076: call UnsafeNativeMethods.GetMessageA
L_007b: brfalse L_0109
L_0080: ldloca.s V_0
L_0082: ldfld MSG.hwnd
L_0087: ldloca.s V_0
L_0089: ldfld MSG.message
L_008e: ldloca.s V_0
L_0090: ldfld MSG.wParam
L_0095: ldloca.s V_0
L_0097: ldfld MSG.lParam
L_009c: call Message.Create
L_00a1: stloc.s V_4
L_00a3: ldc.i4.0
L_00a4: stloc.s V_5
L_00a6: ldloca.s V_0
L_00a8: ldfld MSG.hwnd
L_00ad: call Control.FromChildHandleInternal
L_00b2: stloc.s V_6
L_00b4: ldloc.s V_6
L_00b6: brfalse.s L_00c6
L_00b8: ldloc.s V_6
L_00ba: ldloca.s V_4
L_00bc: callvirt Control.PreProcessMessage
L_00c1: brfalse.s L_00c6
L_00c3: ldc.i4.1
L_00c4: stloc.s V_5
L_00c6: ldloc.s V_5
L_00c8: brtrue.s L_00e7
L_00ca: ldloca.s V_0
L_00cc: call UnsafeNativeMethods.TranslateMessage
L_00d1: pop
L_00d2: ldloc.1
L_00d3: brfalse.s L_00df
L_00d5: ldloca.s V_0
L_00d7: call UnsafeNativeMethods.DispatchMessageW
L_00dc: pop
L_00dd: br.s L_00e7
L_00df: ldloca.s V_0
L_00e1: call UnsafeNativeMethods.DispatchMessageA
L_00e6: pop
L_00e7: ldarg.1
L_00e8: brfalse.s L_0109
L_00ea: ldarg.1
L_00eb: callvirt Form.CheckCloseDialog
L_00f0: ldc.i4.0
L_00f1: ceq
L_00f3: stloc.2
L_00f4: br.s L_0109
L_00f6: ldarg.1
L_00f7: brfalse.s L_010f
L_00f9: ldc.i4.1
L_00fa: ldc.i4.0
L_00fb: ldc.i4.1
L_00fc: ldc.i4.s 100
L_00fe: ldc.i4 255
L_0103: call UnsafeNativeMethods.MsgWaitForMultipleObjects
L_0108: pop
L_0109: ldloc.2
L_010a: brtrue L_0011
L_010f: ldloc.2
L_0110: stloc.s V_7
L_0112: leave.s L_011a
L_0114: pop
L_0115: ldc.i4.0
L_0116: stloc.s V_7
L_0118: leave.s L_011a
L_011a: ldloc.s V_7
L_011c: ret

La version .NET semble faire la même chose que la version VB6: regarder s'il y a des messages en attente dans la file, en traiter un si oui et sinon attendre, là avec MsgWaitForMultipleObjects pendant 100ms.


Xya

Commentaire de Afyn le 15/03/2004 14:10:25

Merci Xya pour ton "étude"...
Je me doutais que DoEvents utilisait le système de message.
(forcément ...)
Ce qui reste flou dans Windows, c'est la façon dont les
messages prennent la priorité.
Et savoir si sleep ... rend la main immédiatement ou pas ?
J'ai pas pour ma par réussi a mesurer, mais je pense
sincérement qu'il rend la main immédiatement...
C 'est cette "propriété"que j'ai exploité avec le WaitableTimer
Et ki me semble la bonne voie... pour attendre sans consommer
du CPU

Encore merci a tous pour vos analyses

Afyn
Navedac
Le savoir faire des cancres...

Commentaire de Alain Proviste le 06/05/2004 00:17:56 administrateur CS

http://www.calbay.com/doevents.htm

zzz

merci Xya pour ce ke tu as fait c interessant.

Neanmoins une chose est sure, pour pouvoir conserver une maximum de "stabilité" sous windows sans trop perdre de performances sous ton soft est lutilisation d'un second thread ki doevents toutes les enièème de secondes.

Commentaire de Alain Proviste le 06/05/2004 00:22:08 administrateur CS

en attendant, pkoi le doevent il éxécute un sleep ? c'est une perte non ?

Commentaire de Xya le 06/05/2004 14:10:39

Une précision encore:
Sleep, SleepEx, WaitForSingleOject(Ex), (Msg)WaitForMultipleOject(Ex) mettent le thread en cours en état d'attente et donc NE consomment PAS de CPU, le temps du CPU étant partagé entre tous les threads en cours d'exécution.

(MSDN: The MsgWaitForMultipleObjects function determines whether the wait criteria have been met. If the criteria have not been met, the calling thread enters the wait state. It uses no processor time while waiting for the conditions of the wait criteria to be met. )

A noter aussi qu'il vaut mieux ne pas utiliser Sleep(Ex) sur des threads qui s'occupent d'une fenêtre (ce qui est généralement le cas avec VB6) puisque comme le thread passe en attente il ne peut plus lire les messages qui lui arrivent, et la fenêtre reste figée.

Xya

Commentaire de Afyn le 06/05/2004 17:10:03

Ca mériterait (pour celui ki aurait le courage) un petit schéma... et kelkes petits exemples pour appuyer toutes ces belles théories.

Afyn

Commentaire de legion91 le 11/08/2004 17:57:33

timer repasse à 0 à minuit logik il est minuit essayez msgbox timer/3600.
Ho!! mais c'est une heure decimal ;-)

Commentaire de lolo31400 le 18/09/2006 19:56:05

bonjour et en pascal une boucle d'attente vous la coderiez comment?

Commentaire de 85bmx85 le 14/04/2008 16:14:08

Bonjour, a tout hasard si quelqun tombe sur ceci :
je suis en vb express (2008) et M.VB il est pas content car monsieur M.VB il conait pas abs donc tout betement :
c'est quoi l'équivalent?

Sinon rapport au tuto :
pas mal du tout tres bonne idée  mais par contre il aurait fallu préciser que sleep ne fait pas juste une pause il stoppe le programme tout entier (plus aucune interaction) comme l'a dit Xya

Commentaire de Renfield le 14/04/2008 16:30:53 administrateur CS

Math.Abs  me semble

Commentaire de 85bmx85 le 16/04/2008 18:52:53

bonne réponse

Commentaire de 85bmx85 le 16/04/2008 18:54:18

tant qu'à faire je précise pour ce qui tournent aussi sous express que DoEvents devient Application.DoEvents
a+

 Ajouter un commentaire


Discussions en rapport avec ce code source dans le forum

boucle infinie [ par damd ] salut a tousune boucle du type :do "code" doeventsloopest-elle infinie si on a pas d'instruction exit doa quoi sert le doeventsmerci do doevents loopuntil [ par fred23 ] Bonjour,Voila mon pb,j'ai une boucleDoDoEventsLoop untilEn fait, DoEvents peut etre sollicité par un Timer.Et je voudrais que, si le timer arrive avan Résumer un DoEvents [ par salazar ] Dans une boucle for j'ins&#232;re un DoEvents pour que Windows traite d'autres tache en attendant que la boucle se termine. Mais si je ferme le progra DoEvents en VB2005 [ par yvesdelorme ] Bonjour,J'ai un problème avec VB2005, je ne sais pas comment remplacer la fonction de VB6 'DoEvents' dans un projet VB2005, Visual Studio 2005 me refu Difficulté pour choisir méthode a appliquer dans une application. [ par Kite37 ] Bonjour !Je suis en train de développer un nouveau jeu qui consiste à écrire les mot d'une liste en cliquant sur des lettres qui défilent à l'écran (v Attendre entre 2 actions [ par kiboumz ] Bonjour,J'aimerais savoir comment faire pour attendre un certain lap de temps entre 2 actions. J'avais pensé utilisé la méthode sleep (de thread), mai Faire une boucle afin d'attendre qu'un fichier txt soit accessible .. [ par nagstef ] Bonjour, dans ce nouveau jour de programmation intense :)) !!Je fais un petit soft qui va r&#233;guli&#232;rement chercher des informations dans un fi pb éxécution méthode activeX [ par inertia ] salut a tous, je developpe un simulateur de commande numérique en ce moment (VB).je me suis programmé un activeX C++ pour gérer l'openGLça fonctionne for...each [ par scoder ] Bonjour, j'ai une petite question concernant la boucle for..eachj'ai plusieurs composants winsock sur mon form serveur et j'aimerai envoyer des donnée Passage de Access a SQL Server [ par gothmilk ] Bonjour, J'ai développé une application VB 6 qui charge les données d'un log dans une base de données access. Au début c'était très lent e


Nos sponsors


Sondage...

Comparez les prix

CalendriCode

Février 2010
LMMJVSD
1234567
891011121314
15161718192021
22232425262728

Consulter la suite du CalendriCode

 
Développement réalisé par Nicolas SOREL (Nix) avec l'aide de : Cyril DURAND et Emmanuel (EBArtSoft), Merci à Vincent pour ses précieux conseils.
CodeS-SourceS.com© Toute reproduction même partielle est interdite sauf accord écrit du Webmaster
CodeS-SourceS.com© est une marque déposée tous droits réservés

Google Coop CodeS-SourceS Google Coop CodeS-SourceS
Temps d'éxécution de la page : 1,014 sec (3)

Nous contacter | Annoncer sur CodeS-SourceS | Mentions légales