Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Algorithmen, Datenstrukturen und Klassendesign (https://www.delphipraxis.net/78-algorithmen-datenstrukturen-und-klassendesign/)
-   -   Delphi Auf Zeitpunkt überwachen (https://www.delphipraxis.net/206104-auf-zeitpunkt-ueberwachen.html)

DaSchwoa 19. Nov 2020 12:45

Auf Zeitpunkt überwachen
 
Hallo
Ich schreibe gerade einen Service und möchte, dass zu einer Bestimmten Uhrzeit eine Prozedur ausgeführt wird.
Bisher habe ich immer einen Timer verwendet. Jede Stunde überprüfen er ob -> (ausgewählt Zeit < Jetzt) dann soll er die Prozedur ausführen.

Jedoch habe ich schon oft gelesen, dass man bloß keinen Timer verwenden soll aber ich kenne auch keine Alternativen. Hätte auch überlegt mit Windows Aufgabenplanung, jedoch habe ich unterschiedliche Zeiten, welche ich aus einem .ini File auslese.

Kann mir da wer weiter helfen?

generic 19. Nov 2020 12:59

AW: Auf Zeitpunkt überwachen
 
Den Link zu Cromis „CRON Scheduler“ in den Artikel auf der "entwickler.de" Webseite besser NICHT verwenden!

Ich hatte einen Artikel zu dem Thema verfasst:
https://entwickler.de/online/develop...al-114967.html

bzw. die Papier-Version:

Entwicker 4.2013
https://kiosk.entwickler.de/entwickl.../back-in-time/

Zusammenfassung:
Du kannst den Windows Scheduler nutzen und mit Delphi die passenden Triggern erstellen, wie diese in deiner INI sind.

Cromis kann jetzt hier gefunden werden:
https://github.com/elvac/CromisLibrary

Der schöne Günther 19. Nov 2020 13:05

AW: Auf Zeitpunkt überwachen
 
Jetzt würde mich aber wirklich der Grund interessieren weshalb man denn keinen Timer verwenden solle...

Delphi.Narium 19. Nov 2020 13:16

AW: Auf Zeitpunkt überwachen
 
Also, das mit dem Timer = seeeeehrrrr böööse halte ich für Quatsch.

Seit gefühlt 25 Jahren nutze ich Timer, ohne dass dabei je ein Problem aufgetreten ist.

Auch in Services hab' ich schon Timer genutzt, problemlos, um damit zu steuern, wann welche Aufgabe zu erledigen ist, z. B. 1 Job um 0:00 Uhr, ein anderer um 3:00 Uhr, weitere stündlich, jeweils zur vollen Stunde plus 15 Minuten (also immer um viertel nach), .... Alles in einem Service. Und der lief über viele Jahre anstandslos.

Zum Zeitpunkt:

Die Zeit in Millisekunden bis zum verlangten Zeitpunkt ausrechnen. Beim Timer das Intervall mit der berechneten Anzahl von Millisekunden belegen und den Timer aktivieren. Der "Auslösefehler", die Pünktlichkeit, liegt in 'nem Bereich von +/- 1 Millisekunde. Wenn man's nicht genauer braucht, sollte das reichen.

Um's zu vereinfachen, kann man sich auch 'nen Nachfolger vom TTimer bauen, der beim Aktivieren (timer.Enabled := True) selbst die Zeitdifferenz ausrechnet und das Intervall setzt und dann die Aktivierung durchführt.

In der Timerroutine wird zuerst der Timer deaktiviert, dann die auszuführende Aufgabe (Prozeduraufruf(e)) erledigt, die Zeit bis zum nächsten Aufruf des Timers berechnet, das Intervall gesetzt und der Timer aktiviert.

Ok: Das heißt dann auch: Pro Job ein Timer, solang man da nicht hunderte von Timern in einem Service nutzt und die nicht alle zeitgleich "zuschlagen", geht das ohne weiteres.

Muss man halt 3 mal täglich zu definierten Zeiten 'ne Datei aus dem Web laden und einmal täglich die verarbeiteten Ergebnisse in 'ner Datenbank speichern und dann daraus einen Report an 'nen bestimmten Mailverteiler senden, sowie 'ne CSV-Datei mit dem Ergebnis an einer bestimmten Stelle im Netz ablegen, ..., geht das. Für zeitkritische Aufgaben ist sowas natürlich nicht geeignet.

Zitat:

Zitat von Der schöne Günther (Beitrag 1477538)
Jetzt würde mich aber wirklich der Grund interessieren weshalb man denn keinen Timer verwenden solle...

Das ist ja das Schöne, man ließt immer nur: Bööööse, darf man nicht. 'ne (wenn auch nur halbwegs) plausiblen Grund hab' ich bisher noch nicht gelesen ;-)

DaSchwoa 19. Nov 2020 13:29

AW: Auf Zeitpunkt überwachen
 
Zitat:

Zitat von Delphi.Narium (Beitrag 1477540)
Also, das mit dem Timer = seeeeehrrrr böööse halte ich für Quatsch.

Danke die Bestätigung habe ich gebrauch :). Jetzt schwimme ich auch gegen den Strom

himitsu 19. Nov 2020 15:30

AW: Auf Zeitpunkt überwachen
 
Das Schöne mit den CRON-Jobs: Wenn kaum etwas gemacht wird, dann braucht der Service/Hintergrundaufgabe auch nicht dauerhaft "aktiv" zu sein.
Dein Programm ist nicht akiv, es wird vom Aufgabenverwaltungsdienst entsprechend der einstellten Zeiten und/oder Events gestartet und wenn fertig, beendet es sich wieder.
"nicht aktiv" = garnicht aktivt, also beendet und auch nicht nur "nichtstuend" sinnlos wartend.

Windows bietet sogar einen Hintergunddienst für Downloads, wo man ewas eintragen kann und wenn es dann da ist, wird das eigene Programm gestartet.
Netterweise werden hier sogar die DialUp-Settings der Netzwerkverbindung beachtet. z.B. das WLAN des HandyHotspots wird nicht mit Updates überflutet und der Traffic aufgebraucht, sondern erst daheim im großen Internetzugang.

Per se wäre es also garnicht nötig, dass man z.B. Dauerhaft mit tausenden aktiven Diensten/TrayIconProgrammen für Updates von irgendwelchen Programmen zugemüllt wird, die ständig im Internet rumwühlen.


Bei uns läuft im Service ein Thread, da einige Dinge auch minütlich erledigt werden.
Nach jedem Durchlauf macht der mindestens 15 Sekunden und maximal bis zu 60 Sekunden (seit Beginn des Durchlaufs) Pause, als Sicherheit, falls mal irgendwas schief läuft und somit nicht dauerhaft alles auslastet.
Und da werden auch paar Methoden mit aufgerufen, Aktionen in größeren Intervallen -> jeweils am Anfang eine Prüfung, ob Now/CurrentTime größer/gleich dem Zeitpunkt der nächsten Ausführung.
z.B.
Delphi-Quellcode:
if (HourOf(Now) = 3) and (LastDate < Date) then begin LastDate := Date; ....... end; // also immer früh um 03:00

Rollo62 20. Nov 2020 06:45

AW: Auf Zeitpunkt überwachen
 
Zitat:

Zitat von Delphi.Narium (Beitrag 1477540)
Die Zeit in Millisekunden bis zum verlangten Zeitpunkt ausrechnen. Beim Timer das Intervall mit der berechneten Anzahl von Millisekunden belegen und den Timer aktivieren.

So würde ich das für exaktes Timing aber nie machen.
Immer nur den Timer als "Ticker" verwenden, und die Auslösezeit per TDateTime Variable festlegen.

Den "Ticker" kann ich mit der gewünschten Genauigkeit laufen lassen,
gerne auch mit variablen Intervallen
(z.B. 15 Min Intervall, wenn noch > 1 Tag Differenz, 1 Min Intervall am selben Tag).

Dann im Timer die Zeit prüfen:
Delphi-Quellcode:
procedure Timer1Timer( ... );
begin
    Timer1.Enabled := False;

    if Now >= FDateTimeAlarm then
    begin
        TueWasDuNichLassenKannst;
    end;

    Timer1.Enabled := True;
end;

So bestimme ich selbst die gewünschte Genauigkeit, auf die direkte Millisekunden verlasse ich mich nur wenn das Intervall im einstelligen Minutenbereich liegt.

Delphi.Narium 20. Nov 2020 09:08

AW: Auf Zeitpunkt überwachen
 
Kommt drauf an, was man machen will.

Zum Dateidownload, 'ner einmal täglichen Datenbankabfrage mit Versand des Ergebnisses per Mail und ca. alle 15 Minuten zu prüfen, ob bestimmte Server erreichbar sind, reicht meine Variante aus. Sie ist einfach, schnell implementiert und lief bisher über Jahre genau und absolut zuverlässig und resourceschonend. Mehr brauch' ich nicht. Bei der Aufgabenstellung wären auch Rundungsdifferenz in der Zeitpunktberechnung von 'ner Minute absolut unkritisch gewesen.

Ob 'ne Prüfung auf Serververfügbar nun zur exakten vollen, viertel, halben und dreiviertel Stunde läuft oder plus/minus 'ne Minute, ist hier irrelevant und 'ne Abweichung von einer Millisekunde ist absolut vernachlässigbar. Und ob die Datenbankabfrage nun jeden Morgen um 03:15 Uhr durchgeführt wird oder 'ne Minute vorher oder nachher ist auch wurscht, zumal man eh nicht kalkulieren kann, wie lange sie genau dauern wird, wieviele Mails aus dem Ergebnis entstehen und versand werden müssen.

Es ging bei meinem Vorschlag nicht um exaktes Timing (wie es für zeitkritische Aufgaben erforderlich sein kann), sondern um eine zuverlässige Regelmäßigkeit. Und die hat die implementierte Variante über Jahre hinweg bewiesen.

Achso: Das "Pollen" auf den exkten Zeitpunkt per immer wieder Abfragen, ob der Zeitpunkt erreicht ist und dabei die Zeiträume zwischen den Abfragen immer weiter verkürzen, bis der Zeitpunkt erreicht ist, war bei den ersten Experimenten in der Implementierung aufwändiger, aber letzlich nicht genauer.

Klar, wenn jemand zwischenzeitlich mal die Systemuhrzeit verstellt, bleibt das Pollen genau und meine Routine geht einmal (ggfls. um die Differenz zwischen Uhrzeit vor der Zeitumstellung und nach der Zeitumstellung) schief, aber dann passt es wieder. Und mehr Genauigkeit war nicht erforderlich.

Es kommt bei der gewählten Methode also drauf an, was man wie genau (oder ungenau) erreichen will.


Alle Zeitangaben in WEZ +1. Es ist jetzt 19:45 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