![]() |
Timer ohne VCL
Hallo zusammen,
ich Suche eine Möglichkeit in einem Thread auf einen bestimmten Zeitpunkt zu warten. Meine Idee war nun die Differenz zwischen dem aktuellen und dem Zielzeitpunkt zu berechnen und dann zu warten. Meine Frage: Wie mach ich das nun am besten? Eine Möglichkeit die ich gefunden habe wäre ein WaitForSingleObject mit dem entsprechenden Intervall, doch ich frage mich ob es dort nicht zu größeren Abweichungen kommen kann. |
Re: Timer ohne VCL
Was denn für einen bestimmten Zeitpunkt?
|
Re: Timer ohne VCL
Bei WaitForSingleObject sollte es eigentlich nicht zu größeren Abweichungen kommen, ist aber letztlich auch nicht genauer als Sleep.
Die normale Variante verwendet Waitable-Timer-Objekte. Du kannst zum Beispiel sagen, dass ein Waitable Timer zu einem bestimmten Zeitpunkt (absolut) oder nach einer bestimmten Zeit (relativ) signalisiert werden soll. Auf den Timer kannst du dann mit einer beliebigen Wait Function warten. |
Re: Timer ohne VCL
Waitable-Timer-Objekte... ich glaube, dass war das Stichwort, was ich gesucht habe!
Vielen Dank! |
Re: Timer ohne VCL
Ich habe nun mal ein bisschen mit diesen Waitable-Timer-Objects rumgespielt. Leider verstehe ich das mit dem APC-Callback nicht. Dieser wird bei mir nicht ausgelöst:
Delphi-Quellcode:
Bei dem Test wird wie gewünscht eine Minute gewartet, der der Callback wird aber nicht aufgerufen. Das mit den APCs durchschaue ich im Moment leider nicht. Ich würde mich freuen, wenn mir jemand auf die Sprünge helfen könnte!
procedure Trigger(lpArgToCompletionRoutine: Pointer; dwTimerLowValue, dwTimerHighValue: DWORD);
begin ShowMessage('Callback...'); end; procedure TForm1.Button1Click(Sender: TObject); var Wecker: SYSTEMTIME; CorrectTriggerTime, TriggerTime: FILETIME; DueTime: LARGE_INTEGER; begin GetLocalTime(Wecker); Wecker.wMinute := Wecker.wMinute +1; SystemTimeToFileTime(Wecker, TriggerTime); LocalFileTimeToFileTime(TriggerTime, CorrectTriggerTime); DueTime.LowPart := CorrectTriggerTime.dwLowDateTime; DueTime.HighPart := CorrectTriggerTime.dwHighDateTime; SetWaitableTimer(WndTimer, DueTime.QuadPart, 0, @Trigger, nil, True); WaitForSingleObjectEx(WndTimer, INFINITE, True); Showmessage('Schluss'); end; |
Re: Timer ohne VCL
Du hast bei den Waitable Timern zwei verschiedene Möglichkeiten: Entweder du wartest auf das Objekt, oder du lässt dich per APC benachrichtigen. Du vermischst hier beides. Dabei passiert folgendes: Wenn der Timer ausgelöst wird, wird zunächst dein Thread aus dem WaitForSingleObjectEx "befreit"; danach wird die APC in die Warteschlange deines Threads gesetzt. Der Thread ist jedoch schon wieder bereit zum Weiterlaufen und hat damit den Zustand, in dem er APCs verarbeiten kann, verlassen.
Du solltest dich jetzt entscheiden: Wenn du WaitForSingleObjectEx verwendest, brauchst du APCs nicht, da du ja direkt erfährst, wann der Timer ausgelöst wurde; wenn du APCs verwendest, brauchst du WaitForSingleObjectEx nicht, sondern musst nur periodisch in den "alertable wait state" gehen, z.B. mit SleepEx. |
Re: Timer ohne VCL
und bist'e dir mit der Aufrufkonvention für dein Trigger ganz sicher? (ich hätte da jetzt ein stdcall erwartet)
aber so wie der Code in #5 ist, würde da auch ein Sleep ausreichen. PS: der Trigger ist da, damit der Thread weiterlaufen kann und bei Ablauf der Zeit benachrichtigt wird. |
Re: Timer ohne VCL
Zitat:
Zitat:
|
Re: Timer ohne VCL
APCs sind dazu da, damit du WaitForSingleObjectEx nicht brauchst.
|
Re: Timer ohne VCL
Tjo... nur kommt das nicht am Ende aufs gleiche raus? Bei dem einen muss ich ab und an mit WaitForSingleObject nachfragen und bei den APCs muss ich mit SleepEx auch ab und zu die Gelegenheit geben den Callback auszuführen.
|
Re: Timer ohne VCL
In deinem Fall würde ich auf APCs verzichten und lieber mit WaitForSingleObject warten. Aber APCs sind sehr nützlich, wenn du viele Timer hast, weil du dann nicht ein Array von Handles brauchst, auf das du wartest und dir dann auch noch merken musst, was du beim Signalisieren ausführen musst.
|
Re: Timer ohne VCL
drum sagte ich ja ... wenn eh gewartet werden soll, warum dann nicht einfach nur Sleep bzw. SleepEx, falls es auch vor der Zeit abbrechbar sein soll?
Delphi-Quellcode:
Sleep(1*60*1000);
|
Re: Timer ohne VCL
Interessante Sache diese APCs... vielen Dank für die Hilfe! :dp:
@himitsu: Es geht da z.T. um größere Zeiträume (Tage bis Wochen) und ich meine gelesen zu haben, dass Sleep da nicht so genau ist. |
Re: Timer ohne VCL
je größer der Zeitraum, desto genauer wird Sleep
MSDN (SleepEx) If dwMilliseconds is less than the resolution of the system clock, the thread may sleep for less than the specified length of time. If dwMilliseconds is greater than one tick but less than two, the wait can be anywhere between one and two ticks, and so on. |
Re: Timer ohne VCL
Oje... ist es dann völlig Wurst was ich nehme, oder gibt es hier und da noch Vor- und Nachteile?
|
Re: Timer ohne VCL
Siehe Beitrag #11.
|
Re: Timer ohne VCL
Die Frage ist ja Sleep vs. Waitable-Timer... Bei Sleep denke ich ist das beenden unangenehmer... daher bleib ich bei den Timer-Viechern :)
|
Re: Timer ohne VCL
Du könntest auch SleepEx nehmen und zum Beenden einen APC schicken.
|
Alle Zeitangaben in WEZ +1. Es ist jetzt 04:49 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-2025 by Thomas Breitkreuz