begin process at 2008 07 04 23:27:48
1 204 973 membres
490 nouveaux aujourd'hui
14 118 membres club

Vous ne trouvez pas de réponse à votre problème ? Alors posez la question dans le forum.
Souvenez-vous qu'il n'y a jamais de question bête, mais rester dans l'ignorance parce que l'on n'ose pas poser une question, ça c'est une erreur !

SLEEP NON BLOQUANT


Information sur la source

Catégorie :Trucs & Astuces Niveau : Initié Date de création : 22/08/2003 Date de mise à jour : 22/08/2003 15:59:01 Vu / téléchargé: 4 595 / 299

Note :
9,67 / 10 - par 3 personnes
9,67 / 10

  • 1

  • 2

  • 3

  • 4

  • 5

  • 6

  • 7

  • 8

  • 9

  • 10

Commentaire sur cette source (15)
Ajouter un commentaire et/ou une note

Description

Tous ceux qui ont utilisés Sleep dans une application VCL savent que l'application se retrouve irrémédiablement bloquée durant toute la durée du Sleep... J'ignore s'il existait déjà des fonctions permettant d'éviter ce problème, mais voici une fonction permettant d'éviter ce désagrément :

Source

  • procedure Pause(t: DWORD); register;
  • asm
  • push ecx
  • push ebx
  • mov ecx, eax
  • call GetTickCount
  • mov ebx, eax
  • @attente:
  • push ebx
  • push ecx
  • mov eax, Application
  • call [EAX].TApplication.ProcessMessages
  • push 1
  • call Sleep
  • pop ecx
  • pop ebx
  • call GetTickCount
  • sub eax, ebx
  • cmp eax, ecx
  • jnae @attente
  • pop ebx
  • pop ecx
  • end;
procedure Pause(t: DWORD); register;
asm
  push ecx
  push ebx
  mov ecx, eax
  call GetTickCount
  mov ebx, eax
@attente:
  push ebx
  push ecx
  mov eax, Application
  call [EAX].TApplication.ProcessMessages
  push 1
  call Sleep
  pop ecx
  pop ebx
  call GetTickCount
  sub eax, ebx
  cmp eax, ecx
  jnae @attente
  pop ebx
  pop ecx
end;

Conclusion

J'ai essayé de l'optimiser au maximum, mais si on peut mieux faire, n'hésitez pas à laisser un message ! De plus, cette fonction devrait être assez universelle, et fonctionne sur Delphi 5 et ultérieurs.

Le sleep dans la boucle ne sert qu'à rendre la main à Windows, s'il existe une fonction comme pthread_yield sous Windows, je ne la connais pas mais il serait préférable de l'utiliser, je pense.
Pour les "Membres Club", vous pouvez télécharger directement un fichier contenu dans le zip sans télécharger le zip en entier !

Télécharger le zip

  • signaler à un administrateur
    Commentaire de korgis le 23/08/2003 15:21:41

    Fonctionne parfaitement sous Delphi 4.
    Me semble remplacer très avantageusement Sleep !
    Bravo et merci pour ce code, Nebula :-)

  • signaler à un administrateur
    Commentaire de cam91 le 23/08/2003 23:44:37

    Tout d'abord merci beaucoup pour ton code qui répond à un problème essentiel de gestion du temps. Je l'ai testé et il fonctionne à merveille sous Delphi 3, cependant pour la version 7 que j'utilise, le compilateur ne reconnait pas l'instruction call[EAX].TApplication.ProcessMessages. J'ai donc repris l'idée pour l'appliquée aux dernières versions de Delphi:

    procedure TForm1.Pause2(t:DWORD);
    asm
    push esi
    push edi
    mov  esi,edx
    call GetTickCount
    add  esi,eax
    mov  edi,Application
    @attente:
       push 1
       call sleep
       mov  eax,edi                                   //ou rien (selon version)
       call TApplication.ProcessMessages //où call [edi].TApplication.ProcessMessages
       call GetTickCount
       cmp  esi,eax
    jae @attente
    pop  edi
    pop  esi
    end;

    Comme tu peux le constater j'ai également optimisé le code qui devient plus court, en effet les 3 call ne modifient pas les registres ebx,esi et edi. Mais on peut toujours faire mieux ;-)

  • signaler à un administrateur
    Commentaire de Nebula le 24/08/2003 16:02:57

    Tout d'abord merci pour vos compliments et remarques, çà fait bien plaisir ! ;-)

    Et merci cam91 pour la version améliorée, c'est effectivement plus propre (et un poil plus rapide, lol) sans les push/pop dans la boucle ! Mais on doit pouvoir utiliser des tests dans le code, non ? Un peu comme les #ifdef en C, çà ferait une seule procédure pour toutes les versions de Delphi... J'ai déjà vu des codes qui en utilisaient, mais je sais plus comment çà marche... Je verrais çà demain au taf, à moins que quelqu'un me coupe l'herbe sous le pied, lol ;-)

  • signaler à un administrateur
    Commentaire de cam91 le 25/08/2003 00:33:13

    J'ai vérifié, on peut effectivement réaliser une compilation conditionelle, pour cela il suffit d'ajouter:

    {$IfDef VER150} //pour Delphi 7
       mov  eax,edi
       call TApplication.ProcessMessages
    {$Else}
       call [EAX].TApplication.ProcessMessages
    {$EndIf}

    VER80 pour Delphi1
    VER90 pour Delphi2
    VER100  pour Delphi3
    VER120  pour Delphi4
    VER130  pour Delphi5
    VER140  pour Delphi6
    VER150  pour Delphi7
    Voila, désolé de t'avoir coupé l'herbe sous les pieds ;-)

  • signaler à un administrateur
    Commentaire de Nebula le 25/08/2003 09:21:49

    lol :)

    C'était effectivement bien çà, dommage qu'on puisse pas faire :

    {$if ver >= 150}
      mov  eax,edi
      call TApplication.ProcessMessages
    {$else}
      call [EAX].TApplication.ProcessMessages
    {$endif}

  • signaler à un administrateur
    Commentaire de yvemoreau le 25/09/2003 17:00:19


    {$IfDef VER140 or higher} // si delphi 6
    mov  eax,edi
    call TApplication.ProcessMessages
    {$else}
    call [EAX].TApplication.ProcessMessages
    {$endif}

    moi aussi sous delphi6 ça plantait

    reste à voir si ça fonctionne sous 5 ?

    bravo encore !

    yve

  • signaler à un administrateur
    Commentaire de AnAcOnDa le 17/11/2003 06:48:14

    (sous delphi7 même avec les modifications c'est toujours bloquant)

  • signaler à un administrateur
    Commentaire de Zeroc00l le 02/02/2004 23:29:52

    J'comprend pôôô !
    Je suis sous delphi 6 là... j'ai recopié la fonction de cam91, essayé avec des valeurs allant de 1 à 4 000 000 000 ca ne fait aucune différence ... C'est quoi ce bins ?
    Sinon je vais passer à delphi 7... si je résume, je dois passer à quelS codeS (mieux optimisé etc ...) ???

    MERCI d'avance !

  • signaler à un administrateur
    Commentaire de Sylvainlefou le 27/03/2004 10:36:23

    Semble ne pas marcher sous delphi 7 et XP

  • signaler à un administrateur
    Commentaire de retd le 02/07/2004 16:27:40

    Juste une info pour tester la version de Delphi sur une plage:
    {$IF RTLVersion >= 14} // si delphi6 ou supérieur
    ...
    {$IFEND}

    RTLVersion est définie dans System.pas

    @+
    Manu

  • signaler à un administrateur
    Commentaire de Filipe35 le 30/10/2005 23:11:52

    Delphi 7 et moi ca me bloque tout, ^^

    pas grave mais merci ;)

  • signaler à un administrateur
    Commentaire de LeGrizz le 17/01/2006 17:36:10

    Je n'ai aucun problème sous Delphi 7 et ça résoud parfaitement mon problème.

    Merci

  • signaler à un administrateur
    Commentaire de JulioDelphi le 26/01/2007 17:04:12 administrateur CS

    OUIN ! ça bloque aussi pour moi :'( Delphi 7 Enterprise.
    Quelqu'un une autre soluce pour faire une pause, une attente sans bloquer ? =) merci

  • signaler à un administrateur
    Commentaire de intik le 30/03/2007 02:42:01

    Ne marche pas avec Delphi 2005...

    Voila une version qui marche mais bon... jprefere un timer pour plus de fluidité...

    http://www.asmfr.com/article.aspx?Val=130

    à voir aussi

    http://www.delphifr.com/codes/ATTENDRE-SECONDES-DANS-BOUCLE_12585.aspx

    Merci quand meme pour la source ;)

  • signaler à un administrateur
    Commentaire de manu1506 le 20/06/2007 15:40:43

    Et utiliser un Timer, ce ne serait pas plus simple?

Ajouter un commentaire

Pub



Appels d'offres

CalendriCode

Juillet 2008
LMMJVSD
 123456
78910111213
14151617181920
21222324252627
28293031   

Boutique

Boutique de goodies CodeS-SourceS