Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Sonstige Fragen zu Delphi (https://www.delphipraxis.net/19-sonstige-fragen-zu-delphi/)
-   -   Delphi Eigenen Timer schreiben (https://www.delphipraxis.net/129450-eigenen-timer-schreiben.html)

bumpelwumpel 19. Feb 2009 12:30


Eigenen Timer schreiben
 
Hi,

ich möchte für ein Programm eine Timer schreiben.
Dafür will ich die GetTickCount Funktion nutzen. Nur funktioniert es irgendwie nicht richtig.

Delphi-Quellcode:
procedure TForm1.Timer(dauer: integer);
var systime,zaehler: integer;
begin
  zaehler:=0;
  systime:=GetTickCount;
  while dauer>zaehler do
  begin
        if (systime+1000)<=GetTickCount then begin
            Inc(zaehler);
            ListBox1.Items.Add(InttoStr(zaehler)); //zum test der ausgabe
            systime:=GetTickCount;
        end;
  end;
end;
Das Programm scheint die Schleife auszuführen, aber die CPU Auslastung geht auf 100% und das Programm reagiert für die in der Variablen "dauer" nicht mehr.
Wenn die Zeit abgelaufen ist, bringt das Programm die Testausgabe auf einen Schlag.

Was läuft bei dieser Schleife schief?

Und ich hab nochmal eine Frage. Wie kann ich den Timer deklarieren, dass das Programm ihn aufrufen kann und dann für die mitgegebene Zeitdauer pausiert?

mfg bumpelwumpel

Neutral General 19. Feb 2009 12:37

Re: Eigenen Timer schreiben
 
Hi,

Es läuft nichts schief, aber du solltest in jedem Schleifendurchlauf

Delphi-Quellcode:
Application.ProcessMessages;
aufrufen.

Allerdings ist das keine gute Umsetzung für einen Timer find ich...

himitsu 19. Feb 2009 12:41

Re: Eigenen Timer schreiben
 
Wozu bitte einen eigenen Timer erstellen?

Und klar, daß die Last auf 100% hoch geht, schließlich führst du dort eine "schnelle" Schleife aus,
wo STÄNDIG dieses "if (systime+1000)<=GetTickCount then begin" ausgeführt wird.

für dein Probleme würde sich ein Sleep eignen, was die CPU-Last begrenzt:
Delphi-Quellcode:
procedure TForm1.Timer(dauer: integer);
var systime,zaehler: integer;
begin
  zaehler:=0;
  systime:=GetTickCount;
  while dauer>zaehler do
  begin
      if (systime+1000)<=GetTickCount then begin
          Inc(zaehler);
          ListBox1.Items.Add(InttoStr(zaehler)); //zum test der ausgabe
          systime:=GetTickCount;
      end else Sleep(10);
      //Application.ProcessMessages;
  end;
end;
wobei eigentlich auch dieses ausreicht:
Delphi-Quellcode:
procedure TForm1.Timer(dauer: integer);
var systime,zaehler: integer;
begin
  zaehler:=0;
  systime:=GetTickCount;
  while dauer>zaehler do
  begin
    Sleep(1000);
    Inc(zaehler);
    ListBox1.Items.Add(InttoStr(zaehler)); //zum test der ausgabe
    //Application.ProcessMessages;
  end;
end;
[add]
ohne Application.ProcessMessages; entspräche beides deiner bisherigen Funktionsweise, nur ohne die 100% CPU-Last.
[/add]

[add2]
jo. das gute alte Delay gibt's ja och noch :angel2:
Delphi-Quellcode:
procedure TForm1.Timer(dauer: integer);
var systime,zaehler: integer;
begin
  zaehler:=0;
  systime:=GetTickCount;
  while dauer>zaehler do
  begin
    Delay(1000);
    Inc(zaehler);
    ListBox1.Items.Add(InttoStr(zaehler)); //zum test der ausgabe
  end;
end;
[/add2]


aber nochmal wozu einen eigenen Timer, wo es doch eine fertige Komponente gibt, welche nicht ständig vegleich durchführt. :gruebel:


Delphi-Quellcode:
type
  TForm1 = class(TForm)
    Timer1: TTimer;
    procedure Timer1Timer(Sender: TObject);
  private
    { Private-Deklarationen }
    Timer1Count: Integer;
    procedure Timer(dauer: integer);
  end;

procedure TForm1.Timer(dauer: integer);
begin
  Timer1Count := dauer div Timer1.Intervall;
  Timer1.Enabled := True;
end;

procedure TForm1.Timer1Timer(Sender: TObject);
begin
  Timer1.Tag := Timer1.Tag + 1;
  If Timer1.Tag >= Timer1Count Then Timer1.Enabled := False;
  ListBox1.Items.Add(IntToStr(Timer1.Tag)); //zum test der ausgabe
end;
[edit]
jupp, das mit Application.ProcessMessages; ist keine schlechte Idee, denn solange deine Timer-Prozedur läuft, ist die VCL gesperrt.

sirius 19. Feb 2009 12:46

Re: Eigenen Timer schreiben
 
Und schwuppdiwup (Application.Processmessages+sleep) sind wir wieder bei Hagens Delay und der Frage warum nicht ein Timer-Event.

bumpelwumpel 19. Feb 2009 13:02

Re: Eigenen Timer schreiben
 
Zitat:

Zitat von himitsu

Delphi-Quellcode:
type
  TForm1 = class(TForm)
    Timer1: TTimer;
    procedure Timer1Timer(Sender: TObject);
  private
    { Private-Deklarationen }
    Timer1Count: Integer;
    procedure Timer(dauer: integer);
  end;

procedure TForm1.Timer(dauer: integer);
begin
  Timer1Count := dauer div Timer1.Interval; //<-- Wozu die Dauer durch das Interval teilen?
  Timer1.Enabled := True;
end;

procedure TForm1.Timer1Timer(Sender: TObject);
begin
  Timer1.Tag := Timer1.Tag + 1;
  If Timer1.Tag >= Timer1Count Then Timer1.Enabled := False;
  ListBox1.Items.Add(IntToStr(Timer1.Tag)); //zum test der ausgabe
end;

Hey, danke.
Nun ich wollte mal ausprobieren wie man einen Timer machen könnte.
Das mit Application.Processmessages funktioniert gut doch ich benutz doch lieber den internen Timer. (Ich hatte mal ziemliche Probleme mit ihm, deshalb wollte ich ihn nicht benutzen. Doch der Code von himitsu funktioniert.)

himitsu 19. Feb 2009 13:13

Re: Eigenen Timer schreiben
 
Zitat:

Wozu die Dauer durch das Interval teilen?
Wenn du Intervall auf 1000 stellt, dann entspräche dieses deiner alten Funktion.

da wird ja alle etwa einer Sekunde was in's Memo geschrieben und das für die Zeit von Dauer ... also (Dauer / 1000) Mal.

für die Dauer hab ich hier einfach mal die Intervalldauer des Timers genommen :angel:

Es wird also Timer1Count Mal in Timer1.Intervall-Millisekunden-Intervallen das Ereignis ausgeführt,
also Timer1Count * Timer1.Intervall, was wiederum etwa Dauer entspricht.


PS: TTimer nutzt intern nur einen Windows-Timer, welcher dem Programm bzw. der TTimer-Komponente, alle Timer.Intervall Millisekunden, eine Windowsbotschaft (Message) schickt.

Heißt die Komponente hat eigentlich nicht viel zu tun und produziert deshalb fast keine CPU-Belastung.


Was hattest du denn mal für Probleme mit TTimer?


Alle Zeitangaben in WEZ +1. Es ist jetzt 19:48 Uhr.

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