Entwickler-Ecke
Sonstiges (Delphi) - timer arbeitet sehr unpräzise bzw. setzt zweitweise aus
BigBasti - Di 31.01.06 22:06
Titel: timer arbeitet sehr unpräzise bzw. setzt zweitweise aus
ich habe in mein programm einen timer gepackt, der die Sekunden und Minuten anzeigen soll, doch kommt es zeitweise vor, dass er Sekunden überspringt und zum beispiel von 12:12 (Minuten : Sekunden) auf 12:15 springt. Der Intervall des ontimer ereignisses ist 1000 (also genau eine sekunde), hier mal der code:
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12:
| procedure Tform1.Timer1Timer(Sender: TObject); begin if sek<59 then sek:=sek+1 else begin sek:=0; if min<59 then min:=min+1 else min:=0; end;
uhrlabel.caption:='Zeit: ' + inttostr (st) + ':' + inttostr (min) + ' Uhr'; end; |
kann mir jemand helfen, dieses problem zu lösen? wäre supernett :-D
UGrohne - Di 31.01.06 22:17
Wieso nimmst Du dafür nicht die Systemzeit? Dort kannst Du auch bei 0 anfangen, wenn Du zu einem bestimmten Zeitpunkt die Systemzeit abgreifst (z.B. in OnShow):
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30:
| type TForm1 = class(TForm) Timer1: TTimer; procedure Timer1Timer(Sender: TObject); procedure FormShow(Sender: TObject); private time: TDateTime; public end;
var Form1: TForm1;
implementation
{$R *.dfm}
procedure TForm1.Timer1Timer(Sender: TObject); begin Caption := TimeToStr(Now-time); end;
procedure TForm1.FormShow(Sender: TObject); begin time := Now; end;
end. |
Der Timer an sich ist halt ein wenig ungenau, da man nicht voraussagen kann, wann die Anwendung wieder Prozess-Zeit zugewiesen bekommt. Aber mit Hilfe der Systemzeit kannst Du vermeiden, dass diese Sprünge Einfluss auf Deine Zähler haben.
digi_c - Mi 01.02.06 09:25
Oder du benutzt einen HighPerformance Timer wie er z.B. bei Spielen eingesetzt wird. Aber ich weiß nicht ob das deinem Problem angemessen ist.
Muetze1 - Mi 01.02.06 09:36
digi_c hat folgendes geschrieben: |
Oder du benutzt einen HighPerformance Timer wie er z.B. bei Spielen eingesetzt wird. Aber ich weiß nicht ob das deinem Problem angemessen ist. |
Dieser ist zum Timing gut, aber nicht zum Triggern. Er hat kein Ereignis und muss daher gepollt werden - bringt daher mehr Nachteile als Vorteile.
BigBasti - Mi 01.02.06 12:32
vielen dank, ich werde es mal mit der systemzeit versuchen! wenns geklappt hat, sag ich bescheid :-D
edit: joar klappt so weit, nun hab ich aber ein paar fragen zum typ tdatetime!
ich möchte in meinem programm einen "schnelleren tagesablauf" (blöde formulierung) simulieren, deshalb benötige ich nur das anzeigen von Minuten (wobei eine minute einer sekunde in echtzeit ensprechen soll) und der stunden (wobei eine stunde einer minute in echtzeit entsprechen soll, also 60 sekunden in echtzeit). demzufolge soll die ausgabe in etwa wie 23:45 sein (Stunde:Minute), also müsste ich auch noch dafür sorgen, dass die echtzeitminuten im tdatetime nur bis 24 gehen (da sie im programm ja die stunden repräsentieren) und die echtzeitstunden nicht ausgegeben werden.
ist so etwas mit tdatetime verwirklichbar oder gibt es eine andere möglichkeit dies zu erreichen??
alzaimar - Mi 01.02.06 13:13
Kleiner Nachtrag:
Ein TTimer ist nicht wirklich eine Uhr, die knallhart immer ein Ereignis auslöst (schön wärs). Windows verwaltet diese Timer und verschickt entsprechende WM_TIMER Nachrichten. Das ist natürlich blöd, wenn die Anwendung gerade in einer dicken Schleife ist, und die Nachrichten gar nicht abgearbeitet werden.
Abhilfe: Immer mal wieder 'Application.ProcessMessages' aufrufen. Dann klappt das auch mit dem Timer besser. Da es keine hochpräzise Quarzuhr ist, sondern nur eine Softwarelösung, kann man damit keinen Zähler hochzählen und dann erwarten, daß das Ergebnis genau ist. Die eingebaute Uhr (Time) ist dafür jedoch genau genug (+/- 20ms).
digi_c - Mi 01.02.06 13:39
Ich habe festgestellt, das es aber auch Probleme gibt, wenn du z.B. mit dem Mauscursor auf die Fensterleisten Symbole(Minimieren,Schließen,..) gehst und dann ein Hint erscheint.
BigBasti - Mo 06.02.06 23:06
ok ich habe nun folgendes festgestellt:
wenn ich eine variable mit dem timer mitlaufen lasse (siehe ganz oben) wird dieser zwar tatsächlich jede sekunde ausgelöst (Interval ist 1000) jedoch wird die variable, die eigentlich bei jedem aufruf nur um eins erhöht werden soll, um zwei oder sogar 3 erhöht (und das jede sekunde)!
kann mir jemand diese unregelmäßigkeit erklären? der timer wird doch korrekt aufgerufen oder? warum wird der wert der variable nicht richtig erhöht?
UGrohne - Mo 06.02.06 23:14
Also ich hab Dein Code oben mal überprüft und es ausprobiert. Bei mir funktioniert das einwandfrei. Wie hast Du denn festgestellt, dass die Variable um mehr als 1 erhöht wird? Mit dem Debugger?
Und wieso nimmst Du nicht die Systemzeit als "Taktgeber", wie ich es Dir oben geschildert habe?
Spaceguide - Mo 06.02.06 23:57
Ich habe auch dieses Timer-Problem. Probiert es mal aus: Setzt einen Timer auf das Form, der z.b. einen Wert erhöht und ins MouseMove des Forms ein Sleep(10). Solange man die Maus bewegt wird das TimerEvent nie gefeuert.
Amateur - Di 07.02.06 00:55
ja vielleicht weil sleep den hauptthread komplett lahm legt und damit auch den timer.. also entweder sleep und nen extra timer thread oder anstatt sleep nen delay selbst schreiben und zwar mit application.processmessages...
Spaceguide - Di 07.02.06 02:05
Aber nach dem Sleep werden wieder Messages verarbeitet bzw. an das Form geschickt, wie z.B. die Mausbewegung. Es wird jedoch nie eine Message an den Timer geschickt.
King_Crasher - Di 07.02.06 11:52
Der folgende Quelltext zeigt die Systemuhr an:
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7: 8:
| procedure TForm1.Timer1Timer(Sender: TObject); var DateTime : TDateTime; str : string; begin DateTime := Time; str := TimeToStr(DateTime); Caption := str; |
BigBasti - Mi 08.02.06 11:06
ich möchte es nicht mit der systemzeit machen, da bei ich etwas aus der zeit auslesen muss und (siehe oben) die minuten in sekundenschritten und die stunden in minutenschritten vergehen sollen, wodurch die systemzeit unpraktisch ist, da ihre minutenschritte logischerweise bis 60 gehen, ich aber diese nur bis 24 laufen lassen möchte. klingt veriwirrend, daher das schema was ich meine:
die systemzeit gibt aus:
04:12:45 (in Stunden/Minuten/Sekundenschritten)
Stunde:Minute:Sekunde
ich möchte das ganze so haben:
12:45 (in Minuten/Sekundenschritten)
Stunde:Minute (deshalb soll der erste wert, der sich ja im minutentakt erhöht, nur bis 24 gehen können)
ich hoffe aus meinen aufzeichnungen wird jemand schlau
Basti
digi_c - Mi 08.02.06 11:49
Schau mal in die DtaeUtils Unit dort sind schöne Befehle zum auseinanderpflücken z.B. Dayof(),DecodeXYZ...
azubi_20 - Mi 08.02.06 11:51
Also, hier eine Lösung mit einem sicheren Zähler (weil von Systemzeit abgeleitet) :
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30: 31: 32: 33: 34: 35: 36: 37: 38: 39: 40: 41: 42: 43: 44: 45: 46: 47: 48:
| private procedure init;
var std, min, sec, msec : Word; zeit : TDateTime; insec : LongInt; sichererZaehler : LongInt; vtime :TDateTime; initsec : LongInt;
procedure TForm1.init; begin vtime := Now; DecodeTime(vtime, std, min, sec, msec); initsec := std * 3600 + min * 60 + sec; end;
procedure TForm1.Timer1Timer(Sender: TObject); begin DecodeTime(Now, std, min, sec, msec); insec := std*3600 +min*60 +sec;
sichererZaehler := insec-initsec-1;
uhrlabel.Caption := inttostr(sichererZaehler div 60)+' : '+inttostr(sichererZaehler mod 60);
if uhrlabel.Caption = '23 : 59' then init; end;
procedure TForm1.Button1Click(Sender: TObject); begin init; timer1.Enabled := true; end; |
BigBasti - Do 09.02.06 08:35
damit sollte es klappen, danke! :-D
ich probiers mal aus und wenn es funktioniert, sag ich bescheid.
Entwickler-Ecke.de based on phpBB
Copyright 2002 - 2011 by Tino Teuber, Copyright 2011 - 2025 by Christian Stelzmann Alle Rechte vorbehalten.
Alle Beiträge stammen von dritten Personen und dürfen geltendes Recht nicht verletzen.
Entwickler-Ecke und die zugehörigen Webseiten distanzieren sich ausdrücklich von Fremdinhalten jeglicher Art!