TUTO : TECHNIQUE POUR ATTENDRE

Renfield Messages postés 17287 Date d'inscription mercredi 2 janvier 2002 Statut Modérateur Dernière intervention 27 septembre 2021 - 13 mars 2004 à 06:57
85bmx85 Messages postés 16 Date d'inscription lundi 24 décembre 2007 Statut Membre Dernière intervention 26 mai 2012 - 16 avril 2008 à 18:54
Cette discussion concerne un article du site. Pour la consulter dans son contexte d'origine, cliquez sur le lien ci-dessous.

https://codes-sources.commentcamarche.net/source/21180-tuto-technique-pour-attendre

85bmx85 Messages postés 16 Date d'inscription lundi 24 décembre 2007 Statut Membre Dernière intervention 26 mai 2012
16 avril 2008 à 18:54
tant qu'à faire je précise pour ce qui tournent aussi sous express que DoEvents devient Application.DoEvents
a+
85bmx85 Messages postés 16 Date d'inscription lundi 24 décembre 2007 Statut Membre Dernière intervention 26 mai 2012
16 avril 2008 à 18:52
bonne réponse
Renfield Messages postés 17287 Date d'inscription mercredi 2 janvier 2002 Statut Modérateur Dernière intervention 27 septembre 2021 74
14 avril 2008 à 16:30
Math.Abs me semble
85bmx85 Messages postés 16 Date d'inscription lundi 24 décembre 2007 Statut Membre Dernière intervention 26 mai 2012
14 avril 2008 à 16:14
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
lolo31400 Messages postés 1 Date d'inscription lundi 18 septembre 2006 Statut Membre Dernière intervention 18 septembre 2006
18 sept. 2006 à 19:56
bonjour et en pascal une boucle d'attente vous la coderiez comment?
cs_legion91 Messages postés 216 Date d'inscription mercredi 5 février 2003 Statut Membre Dernière intervention 15 décembre 2010
11 août 2004 à 17:57
timer repasse à 0 à minuit logik il est minuit essayez msgbox timer/3600.
Ho!! mais c'est une heure decimal ;-)
Afyn Messages postés 608 Date d'inscription samedi 3 août 2002 Statut Membre Dernière intervention 22 décembre 2016
6 mai 2004 à 17:10
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
Xya Messages postés 103 Date d'inscription lundi 8 juillet 2002 Statut Membre Dernière intervention 24 novembre 2005
6 mai 2004 à 14:10
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
cs_Alain Proviste Messages postés 908 Date d'inscription jeudi 26 juillet 2001 Statut Modérateur Dernière intervention 1 février 2015 2
6 mai 2004 à 00:22
en attendant, pkoi le doevent il éxécute un sleep ? c'est une perte non ?
cs_Alain Proviste Messages postés 908 Date d'inscription jeudi 26 juillet 2001 Statut Modérateur Dernière intervention 1 février 2015 2
6 mai 2004 à 00:17
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.
Afyn Messages postés 608 Date d'inscription samedi 3 août 2002 Statut Membre Dernière intervention 22 décembre 2016
15 mars 2004 à 14:10
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...
Xya Messages postés 103 Date d'inscription lundi 8 juillet 2002 Statut Membre Dernière intervention 24 novembre 2005
15 mars 2004 à 12:40
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
Renfield Messages postés 17287 Date d'inscription mercredi 2 janvier 2002 Statut Modérateur Dernière intervention 27 septembre 2021 74
14 mars 2004 à 20:39
"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
cs_Jack Messages postés 14006 Date d'inscription samedi 29 décembre 2001 Statut Modérateur Dernière intervention 28 août 2015 79
14 mars 2004 à 18:24
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
Renfield Messages postés 17287 Date d'inscription mercredi 2 janvier 2002 Statut Modérateur Dernière intervention 27 septembre 2021 74
14 mars 2004 à 15:54
Xya a tout décris me semble-t'il du fonctionnement de DoEvents....
Xya Messages postés 103 Date d'inscription lundi 8 juillet 2002 Statut Membre Dernière intervention 24 novembre 2005
14 mars 2004 à 15:30
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
Xya Messages postés 103 Date d'inscription lundi 8 juillet 2002 Statut Membre Dernière intervention 24 novembre 2005
14 mars 2004 à 15:22
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 > 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:[<&KERNEL32.Sleep>] ; 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:[<&USER32.PeekMessageA>] ; USER32.PeekMessageA

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

73384956 FF15 30133773 CALL DWORD PTR DS:[<&USER32.DispatchMessageA>] ; USER32.DispatchMessageA

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

73385BE6 8B3D 94143773 MOV EDI,DWORD PTR DS:[<&USER32.SendMessageA>] ; 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
Afyn Messages postés 608 Date d'inscription samedi 3 août 2002 Statut Membre Dernière intervention 22 décembre 2016
14 mars 2004 à 09:56
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
Afyn Messages postés 608 Date d'inscription samedi 3 août 2002 Statut Membre Dernière intervention 22 décembre 2016
14 mars 2004 à 09:53
Bien expliqué.
Un petit bout de code en exemple pourrait être bien venu
également

A+
Afyn
Renfield Messages postés 17287 Date d'inscription mercredi 2 janvier 2002 Statut Modérateur Dernière intervention 27 septembre 2021 74
13 mars 2004 à 06:57
Sleep semble en effet bien indiquée.....

(bonne idée de tuto...)
Rejoignez-nous