Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Sonstige Fragen zu Delphi (https://www.delphipraxis.net/19-sonstige-fragen-zu-delphi/)
-   -   Delphi Alternative zu SLEEP (https://www.delphipraxis.net/66989-alternative-zu-sleep.html)

qb-tim 7. Apr 2006 14:40


Alternative zu SLEEP
 
Ich wollte in meinen Programm eine Wartezeit einbauen. Dazu benutzte ich
Delphi-Quellcode:
//...
sleep(500);
//...
Aber ich bemerkte die Wartezeit garnicht.

An einem Testprogramm ist es noch deutlicher:

Delphi-Quellcode:
//... procedure für den Knopfdruck von Button1
begin
 Label1.Caption:='Tschüß'; //Label1 ist schon vorhanden
 sleep(500);
 close;
end;
//...
Wieso bemerkt man keine Wartezeit?

PS: auch bei einer viel größeren Zahl bemerkt man ebenso nichts!

Evian 7. Apr 2006 14:42

Re: Alternative zu SLEEP
 
naja der Wert den Du an sleep übergibst ist in millisekunden angegeben.. 500 ist dann also eine halbe sekunde. Wenn Du den Wert auf sagen wir 5000 festlegst, solltest Du schon eine Pause bemerken.

qb-tim 7. Apr 2006 14:47

Re: Alternative zu SLEEP
 
Hm,...

Das stimmt. In meinem Testprogramm merkt man schon was wenn sleep über 1500 ist...

In meinem anderen Programm muss ich dann nach was anderem suchen... :oops:

Evian 7. Apr 2006 14:52

Re: Alternative zu SLEEP
 
naja das Problem was ich mit sleep habe ist, dass das Programm einfriert, wenn man einfach nur sleep nutzt, so lange die Prozedur aktiv ist.

Um das zu umgehen, mach ich mir ne Schleife mit prezssmasges drinn. z.B. so:

Delphi-Quellcode:
for i := 1 to 1500 do
  BEGIN
    sleep(1);
    application.ProcessMessages;
  END;
da gibt es sicher noch elegantere Sachen, aber es funtzt auf jeden Fall.

Sharky 7. Apr 2006 14:54

Re: Alternative zu SLEEP
 
Hai ihr zwei,

schaut euch doch man Hagens Beitrag in der CodeLibrary zu dem Thema an.

Edit: Ein "ich" in "euch" umgewandelt hat. :oops:

Angel4585 7. Apr 2006 14:56

Re: Alternative zu SLEEP
 
ich mach das (manchmal) so:

Delphi-Quellcode:
uses DateUtils;
.
.
procedure Wait(Ams : Integer);
var ZP : TDateTime;
begin
ZP:=IncMilliSecond(Now,Ams);
while ZP > Now do
  Application.ProcessMessages;
end;
Ist ne, wie ich finde, sehr amüsante Alternative :stupid:

Evian 7. Apr 2006 15:03

Re: Alternative zu SLEEP
 
nice! :thumb: gefällt mir sogar noch besser, als der Code von Hagen :)

shmia 7. Apr 2006 15:08

Re: Alternative zu SLEEP
 
Zitat:

Zitat von Sharky
schaut ich doch man Hagens Beitrag in der CodeLibrary zu dem Thema an.

Dann kommt hier "Delay revisited #2":
Man sollte den Delay unterbrechen, wenn die Anwendung beendet wurde.
Delphi-Quellcode:
procedure Delay(Milliseconds: Integer);
var
  Tick: DWord;
  Event: THandle;
begin
  Event := CreateEvent(nil, False, False, nil);
  try
    Tick := GetTickCount + DWord(Milliseconds);
    while (Milliseconds > 0) and
          (MsgWaitForMultipleObjects(1, Event, False, Milliseconds, QS_ALLINPUT) <> WAIT_TIMEOUT) do
    begin
      Application.ProcessMessages;
      if Application.Terminated then Exit; // <===== NEU
      Milliseconds := Tick - GetTickcount;
    end;
  finally
    CloseHandle(Event);
  end;
end;

himitsu 7. Apr 2006 15:11

Re: Alternative zu SLEEP
 
Zitat:

Zitat von Evian
Delphi-Quellcode:
for i := 1 to 1500 do
  BEGIN
    sleep(1);
    application.ProcessMessages;
  END;
da gibt es sicher noch elegantere Sachen, aber es funtzt auf jeden Fall.

ProcessMessages braucht Zeit und Sleep mit einer Millisekunde = unmöglich.

Also dürfte da wohl mehr als 1,5 Sekunden rauskommen ;)

Khabarakh 7. Apr 2006 15:15

Re: Alternative zu SLEEP
 
Zitat:

Zitat von Evian
nice! :thumb: gefällt mir sogar noch besser, als der Code von Hagen :)

Ist mein Ironiedetektor kaputt oder ist das wirklich ernstgemeint o.O ?

Evian 7. Apr 2006 15:18

Re: Alternative zu SLEEP
 
Zitat:

Zitat von himitsu
Zitat:

Zitat von Evian
Delphi-Quellcode:
for i := 1 to 1500 do
  BEGIN
    sleep(1);
    application.ProcessMessages;
  END;
da gibt es sicher noch elegantere Sachen, aber es funtzt auf jeden Fall.

ProcessMessages braucht Zeit und Sleep mit einer Millisekunde = unmöglich.

Also dürfte da wohl mehr als 1,5 Sekunden rauskommen ;)

ja wie gesagt elegant war es natürlich nicht.. och man jetzt schäme ich mich total wegen meinem Code.. danke ! :pale: :oops:

Edit: war nen Spaß! ^^

Evian 7. Apr 2006 15:18

Re: Alternative zu SLEEP
 
Zitat:

Zitat von Khabarakh
Zitat:

Zitat von Evian
nice! :thumb: gefällt mir sogar noch besser, als der Code von Hagen :)

Ist mein Ironiedetektor kaputt oder ist das wirklich ernstgemeint o.O ?

ne ehrlich, es an der Systemzeit festzumachen find ich ne coole Idee..

MaBuSE 7. Apr 2006 16:07

Re: Alternative zu SLEEP
 
Zitat:

Zitat von Evian
Zitat:

Zitat von Khabarakh
Zitat:

Zitat von Evian
nice! :thumb: gefällt mir sogar noch besser, als der Code von Hagen :)

Ist mein Ironiedetektor kaputt oder ist das wirklich ernstgemeint o.O ?

ne ehrlich, es an der Systemzeit festzumachen find ich ne coole Idee..

Hagen macht es doch auch an der Systezeit fest.
Oder was denkst Du was GetTickCount macht?

negaH 7. Apr 2006 17:08

Re: Alternative zu SLEEP
 
@shima:

das ist eine sehr gute Idee, aber wenn dann so

Delphi-Quellcode:
  while not Application.Terminated and
        (Milliseconds > 0) and
        (MsgWaitForMultipleObjects(1, Event, False, Milliseconds, QS_ALLINPUT) <> WAIT_TIMEOUT) do
  begin
    Application.ProcessMessages;
    Milliseconds := Tick - GetTickcount;
  end;
Allerdings entspricht das nun nicht mehr EXAKT dem Verhalten was der Name der Funktion suggeriert.

Gruß Hagen

negaH 7. Apr 2006 17:14

Re: Alternative zu SLEEP
 
@Mabuse:

mit dem Unterschied das ich nicht ständig einen leeren Messagequeue mit der sehr langsammen Funktion Application.ProcessMessages permanent polle. Stattdessen warte ich per API brav bis das OS mir per Ereignis mitteilt das es Messages abzuarbeiten gibt. Falls dies nicht der Fall ist wird der Thread komplett schlafen gelegt, also so wie wenn man Sleep() aufrufen würde. Defakto ist meine Funktion nichts anderes wie ein Sleep() aber mit dem Unterschied das vorzeitig bei Bedarf dieses "Sleep" beendet wird um Nachrichten empfangen zu können.

Das einfache Pollen in einer Schleife kostet dagegen viel mehr Rechenzeit. probiers einfach aus und vergleiche beide Methoden indem du mal 10 Minuten warten lässt. Du öffnest den taskmanager und vergleichst die CPU Auslastung.

Naja, steht aber eigentlich alles im verlinkten Thread. Davon abgesehen, sieht mein Source so aus wie der andere ?

Gruß Hagen

MaBuSE 10. Apr 2006 08:40

Re: Alternative zu SLEEP
 
Zitat:

Zitat von negaH
@Mabuse:...Naja, steht aber eigentlich alles im verlinkten Thread. Davon abgesehen, sieht mein Source so aus wie der andere ?

Ich habe schon verstanden was Dein Code macht, ich wollte Evian nur darauf aufmerksam machen, das Du auch den Zeitgeber des Rechners verwendest.

Dein Code gefällt mir sehr gut. Wenn ich nochmal ein Sleep brauche werde ich es warscheinlich genau so machen.
In der Vergangenheit habe ich meist auch nur eine Schleife al la "while zeit>now do application.processmessages;" verwendet. Aber Deine Methode ist eleganter :-)
Die Rechner werden zwar immer schneller, deswegen achten viele Programmierer nicht mehr so auf effizienten Code. Aber es gibt ja auch noch PCs unterhalb der 1000MHz Marke. (Ich verwende z.B. zuhause auch nur einen P3 500.)

negaH 10. Apr 2006 16:41

Re: Alternative zu SLEEP
 
@Mabuse,

das ist ein zu einfacher Vergleich. Wichtig ist der Punkt in welchem Kontext meine Delay() Funktion aufgerufen wird.

Das ordinäre Sleep() lässt einen beliebigen Thread für Millisekunden schlafen. Es gibt aber nun Threads die einen Messagequeue installieren und solche die keinen haben. Der Mainthread eines Prozsses zb. hat eine Nachrichtenschleife ein davon abgespalteter Thread "meistens" nicht.

Eine ordinäre Schleife per GetTickCount() und Application.ProcessMessages würde sich demnach unterschiedlich verhalten jenachdem in welchem Thread sie aufgerufen würde. Defakto sollte man sogar so einen Schleife niemals aus einem abgespalteten Thread heraus aufrufen, da sie nämlich im grunde nicht Threadsafe ist.

Das Delay() verhält sich dazu im Gegensatz entsprechend den Gegebenheiten. In einem Thread ohne Messagequeue verhält es sich fast exakt wie Sleep(), es wartet, kann aber unterbrochen werden wenn der besagte Thread massiv von aussen terminiert wird !
In einem Mainthread zb. würde das Warten immer dann unterbrochen werden wenn zb. der Anwender Messages produziert indem er zb. die Maus über die Formulare bewegt, usw. Die Anwendung friert also nicht ein, noch verbraucht sie unnötig viel Rechnerzeit indem sie unnötig pollt.

Fazit: beide Methoden sind nicht miteinander vergleichbar, es ist sichtbar unterschiedlicher Source, weil sie logisch unterschiedliche Aufgaben erfüllen.

Gruß Hagen


Alle Zeitangaben in WEZ +1. Es ist jetzt 21:58 Uhr.

Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz