Delphi-PRAXiS
Seite 1 von 2  1 2      

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Win32/Win64 API (native code) (https://www.delphipraxis.net/17-win32-win64-api-native-code/)
-   -   Delphi Timer ohne VCL (https://www.delphipraxis.net/134852-timer-ohne-vcl.html)

Mr_G 30. Mai 2009 17:58


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.

quendolineDD 30. Mai 2009 18:13

Re: Timer ohne VCL
 
Was denn für einen bestimmten Zeitpunkt?

Apollonius 30. Mai 2009 18:17

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.

Mr_G 30. Mai 2009 18:34

Re: Timer ohne VCL
 
Waitable-Timer-Objekte... ich glaube, dass war das Stichwort, was ich gesucht habe!
Vielen Dank!

Mr_G 31. Mai 2009 12:06

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:
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;
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!

Apollonius 31. Mai 2009 12:16

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.

himitsu 31. Mai 2009 12:25

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.

Mr_G 31. Mai 2009 12:49

Re: Timer ohne VCL
 
Zitat:

Zitat von himitsu
und bist'e dir mit der Aufrufkonvention für dein Trigger ganz sicher? (ich hätte da jetzt ein stdcall erwartet)

Du hast natürlich Recht...
Zitat:

Zitat von himitsu
PS: der Trigger ist da, damit der Thread weiterlaufen kann und bei Ablauf der Zeit benachrichtigt wird.

Wie meinen?

Apollonius 31. Mai 2009 12:51

Re: Timer ohne VCL
 
APCs sind dazu da, damit du WaitForSingleObjectEx nicht brauchst.

Mr_G 31. Mai 2009 12:59

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.


Alle Zeitangaben in WEZ +1. Es ist jetzt 13:03 Uhr.
Seite 1 von 2  1 2      

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