Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Sonstige Fragen zu Delphi (https://www.delphipraxis.net/19-sonstige-fragen-zu-delphi/)
-   -   Delphi Immer wiederkehrende Aufgaben realisieren (https://www.delphipraxis.net/117965-immer-wiederkehrende-aufgaben-realisieren.html)

RWarnecke 29. Jul 2008 08:48


Immer wiederkehrende Aufgaben realisieren
 
Ich habe folgendes Problem, ich muss drei Aufgaben zu unterschiedlichen Zeiten ausführen. Im Moment realisiere ich es über die Komponente TTimer. Es funktioniert, nur leider nicht im Dauerbetrieb. Wie könnte ich es denn noch realisieren ? Gibt es dazu Befehle oder Komponenten, die genauer sind als TTimer ?

taaktaak 29. Jul 2008 09:35

Re: Immer wiederkehrende Aufgaben realisieren
 
Moin, Moin,
du schreibst, dass es funktioniert, aber nicht im Dauerbetrieb?! Könntest du das konkretisieren...

RWarnecke 29. Jul 2008 09:48

Re: Immer wiederkehrende Aufgaben realisieren
 
Es wird zum Beispiel ein Popupfenster alle x Sekunden oder Minuten angezeigt. Dieses kann variabel eingestellt werden. Wenn ich das Programm nur für maximal eine Stunde laufen lasse, funktioniert es. Geht es aber über die eine Stunde hinaus, dann werden die Popupfenster nichtmehr in dem Rythmus angezeigt, so wie ich es eingestellt habe.

Zur Erklärung: Wenn das Programm ins Tray gesetzt wird, werden die Timer aktiviert und wenn ich es wieder aus dem Tray hole, dann werden die Timer deaktiviert.

taaktaak 29. Jul 2008 10:07

Re: Immer wiederkehrende Aufgaben realisieren
 
Hmmm,
die Timer-Funktionalität wird also nur genutzt, wenn das Programm ins Tray gesetzt ist - sonst nicht?! Nach einer Stunde ändern sich die Intervalle?
Hilft es vielleicht, wenn du mit jeder Deaktivierung des Programms den Timerintervall neu setzt? Aber das wäre irgendwie ein "herumdoktern am Symptom" - seltsam :?:

r2c2 29. Jul 2008 10:42

Re: Immer wiederkehrende Aufgaben realisieren
 
Meine Glaskugel sagt, du hast das Stoppuhr-Problem:

Wenn man so eine Stoppuhr programmiert, wird sie nicht wirklich funktionieren:
Delphi-Quellcode:
// Pseudocode:
OnTimer(Intervall := 1000ms)
begin
  Stoppzeit := Stoppzeit -1s;
end;
Warum: So genau ist Timer nicht(Multitasking und MessageLoop sind dafür verantwortlich). Die Fehler summieren sich mit der Zeit auf. Ist das Intervall größer, dauert es eben länger, bis das Problem auftritt.

Lösung für die Stoppuhr:
Delphi-Quellcode:
// Pseudocode:
OnTimer(Intervall := 1000ms)
begin
  Stoppzeit := (AltesGetTickCount - GetTickCount) div 1000(ms/s);
end;
Dann klapps auch mit dem Nachbarn.... äh... der Stoppuhr.

Ich vermute dein Problem ist durch den selben Effekt begründet. Sie Lösung sollte dann entsprechend auch ähnlich aussehen...

mfg

Christian

taaktaak 29. Jul 2008 10:57

Re: Immer wiederkehrende Aufgaben realisieren
 
Interessant, aaaaber ...
Wenn ich die Aufgabe des Timers in diesem speziellen Fall richtig interpretiere, gehe ich davon aus, dass keine besondere Genauigkeit notwendig ist. Ob ein Fenster 100ms früher oder später erscheint, ist vermutlich irrelevant.
Problematisch ist natürlich, wenn auf das Erreichen eines exakten Intervallwerts geprüft wird. Ist die Lösung dann nicht eine Prüfung auf "Ist-Interval >= Soll-Popup-Intervall"?

r2c2 29. Jul 2008 11:04

Re: Immer wiederkehrende Aufgaben realisieren
 
Zitat:

Zitat von taaktaak
Wenn ich die Aufgabe des Timers in diesem speziellen Fall richtig interpretiere, gehe ich davon aus, dass keine besondere Genauigkeit notwendig ist. Ob ein Fenster 100ms früher oder später erscheint, ist vermutlich irrelevant.

Jo, aber 3600 mal 100ms sind dann doch schon relevant oder? Das is jetzt n Extremfall, klar. Ein Teil der Zeitdifferenz wird sich vermutlich auch wieder wegheben, abver das problem ist da. Wenn es im durchschnitt 10ms sind, sind das 36s pro Stunde und das kann schon signifikant sein...

Zitat:

Ist die Lösung dann nicht eine Prüfung auf "Ist-Interval >= Soll-Popup-Intervall"?
Also sofern ich mich nicht vertan habe, ist mein Code eine Lösung für das Stopp-Uhr-Problem. Was nun im konkreten Fall die Lösung ist, kann cih nicht genau sagen. Daszu hab ich zu wenig Infos. Ich wollte ja auch nur einen Denkansatz liefern. So oder so ähnlich könnte eine Lösung aussehen...

mfg

Christian

taaktaak 29. Jul 2008 11:21

Re: Immer wiederkehrende Aufgaben realisieren
 
Uuuups, natürlich!
Die Ungenauigkeit der TimerIntervalle addiert sich, na klar! Also kann der Aufruf des Timers nur dazu dienen, die Systemzeiten zu vergleichen - die Timerintervalle selbst können nicht zur Berechnung der Zeitdifferenz benutzt werden.
Bei Initialisierung des Timers und Aufruf des Popups wird mit GetTickCount() der Beginn eines neuen Zeitintervalles gesetzt und bei jedem erneutem Timeraufruf mit dem aktuellen Wert von GetTickCount() verglichen. Wenn die definierte Zeitdifferenz erreicht oder überschritten ist, beginnt alles von vorn. Ja, ich denke, das ist die Lösung.

r2c2 29. Jul 2008 11:34

Re: Immer wiederkehrende Aufgaben realisieren
 
Wichtig ist dabei, dass man den Referenzwert von GetTickCount nicht andauernd ändert, sonst hat man wieder das gleiche Problem(vielelicht nach 2h, aber das Problem besteht immer noch). Also diesen Referenzwert genau dann setzen, wenn Timer.Enabled auf true gesetzt wird(so, wie ich das verstanden hab, wenn die Anwendung in die TNA verbannt wird), nicht bei jedem Tick...

mfg

Christian

taaktaak 29. Jul 2008 11:54

Re: Immer wiederkehrende Aufgaben realisieren
 
Hmmm, nicht bei jedem Tick - aber doch wohl bei jedem erfolgten Aufruf des Popup-Fensters. Wenn der Referenzwert nur bei Aktivierung des Timers gesetzt wird, musst du doch unnötig rechnen - oder?

r2c2 29. Jul 2008 12:04

Re: Immer wiederkehrende Aufgaben realisieren
 
Kann ich ohne genaue Infos nicht sagen. Tendentiell macht aber das bisschen Rechnen gar nichts. Die paar Takte sind vernachlässigbar.

mfg

Christian

RWarnecke 29. Jul 2008 12:16

Re: Immer wiederkehrende Aufgaben realisieren
 
Zitat:

Zitat von taaktaak
Hmmm, die Timer-Funktionalität wird also nur genutzt, wenn das Programm ins Tray gesetzt ist - sonst nicht?!

Korrekt so.
Zitat:

Zitat von taaktaak
Nach einer Stunde ändern sich die Intervalle?

Die Intervalle bleiben immer gleich, wenn das Programm im Tray ist.
Zitat:

Zitat von taaktaak
Wenn ich die Aufgabe des Timers in diesem speziellen Fall richtig interpretiere, gehe ich davon aus, dass keine besondere Genauigkeit notwendig ist. Ob ein Fenster 100ms früher oder später erscheint, ist vermutlich irrelevant.

Das ist nicht relevant. Selbst wenn es mal 500ms später oder früher angezeigt wird, macht das nichts aus. Es sollte nur auf jedenfall angezeigt werden. Die Genauigkeit spielt dabei eine nicht so große Rolle.

Startet die TTimer - Komponente den Interval neu, wenn ich Sie deaktiviere und dann wieder aktiviere ? Ich bin bis jetzt zumindest davon ausgegangen.

nahpets 29. Jul 2008 16:47

Re: Immer wiederkehrende Aufgaben realisieren
 
Zitat:

Zitat von RWarnecke
Startet die TTimer - Komponente den Interval neu, wenn ich Sie deaktiviere und dann wieder aktiviere ? Ich bin bis jetzt zumindest davon ausgegangen.

Ja, dadurch kommen immer "Zeitverschiebungen" zustande, die sich im Laufe der Zeit spürbar summieren.
Wie brauchst Du denn den Timer: Immer zur vollen Stunde oder immer zur vollen Minute oder immer nach Abschluß eines Vorganges eine bestimmte Zeitdifferenz.
  • Interval := 60000;

    Timer ein

    Timerereignis
    Timer aus
    irgendwas arbeiten lassen
    Timer ein
Das zweite Timerereignis wird also eine Minute nach dem Abarbeiten des ersten Timerereignisses ausgelöst und nicht zur vollen nächsten Minute.

Eventuell kommst Du ja damit an Deinem Problem "vorbei":

Ein paar Konstanten für definierte Zeiträume
Delphi-Quellcode:
const
  iOneMinute     : Integer =   60000; // eine Minute in Millisekunden
  iFiveMinutes   : Integer =  300000; // Fünf Minuten in Millisekunden
  iFifteenMinutes : Integer =  900000; // Fünfzehn Minuten in Millisekunden
  iOneHour       : Integer = 3600000; // Eine Stunde in Millisekunden
  iOneDay        : Integer = 86400000; // Ein Tag in Millisekunden
Eine Funktion zum Berechnen der Zeitdifferenz bis zum nächsten Timerereignis.
Hier wird der Wert berechnet, der Interval zuzuweisen ist, bevor der Timer eingeschaltet wird.
iTimerInterval ist einer der obigen Konstanten Werte.

Delphi-Quellcode:
function CalcTimerInterval(iTimerInterval : Integer) : Integer;
Var
          dNow : Double;
begin
  // Interval setzen
  // Tagesdatum und Uhrzeit holen
  dNow := Now;
  // Den Tagesanteil holen (= Nachkommastellen).
  dNow := dNow - Trunc(dNow);
  // Rest bis Mitternacht holen.
  dNow := 1 - dNow;
  // Nachkommastellen mal Millisekunden pro Tag
  Result := Trunc(dNow * iOneDay);
  // wir benötigen den Rest bis zum angegeben Interval, damit der Timer
  // zur nächsten Minute, Stunde, 0 Uhr ... aktive wird.
  // (Der durchschnittliche Rechenfehler liegt bei 500 Millisekunden.)
  Result := (Result mod iTimerInterval);
end;
Habe einige Routinen zum Systemmonitoring, bei denen ich diese Berechnung einsetze. Die Routinen "schlagen" zur vollen Stunde, um Mitternacht, alle vollen fünf Minuten... zu. Die Abweichung durch das Berechnen ist immer kleiner 1 Sekunde. Damit kann ich für meinen Bedarf leben.

Stephan

Apollonius 29. Jul 2008 17:23

Re: Immer wiederkehrende Aufgaben realisieren
 
Bei einem so lang laufenden Timer kommt mir ein Waitable Timer in den Sinn. Wenn man ihn APCs auslösen lässt, ist das genauer als die Lösung mit TTimer und einfacher als Lösungen mit GetTickCount.

RWarnecke 29. Jul 2008 18:26

Re: Immer wiederkehrende Aufgaben realisieren
 
Die Timer sollen variabel sein. Der User soll sie anhand von Sekunden einstellen können, wann die Popups angezeigt werden. Diese Zeitverschiebung wie Ihr sie hier beschreibt, würde ja nur zustande kommen, wenn das Programm immer wieder aus dem Tray geholt wird und wieder zurück gelegt wird. Nur ist das bei meinem Test nicht der Fall. Das Programm wird gestartet und unten ins Tray gelegt, ohne irgendwas damit zu machen. Ich habe im Programm insgesamt 4 Timer. Davon wird 1 Timer beim starten des Programms aktiviert und die restlichen 3 Timer werden aktiviert, wenn das Programm in den Tray geht. Der eine Timer, der beim Starten des Programms aktiviert wird, arbeitet zuverlässig. Nur die drei Timer, die beim ablegen ins Tray aktiviert werden, arbeiten gut nach einer Stunde nicht mehr korrekt. Das ist das was ich nicht verstehe.

Das Programm läuft ohne irgend ein Zugriff oder Benutzung vom User. Es werden nur die Popups erzeugt und angezeigt.

Edit:
Wie sieht das aus, mit dem Befehl SetTimer ? Ist der vielleicht besser als die TTimer-Komponente ?

Apollonius 29. Jul 2008 18:52

Re: Immer wiederkehrende Aufgaben realisieren
 
TTimer ist nur eine Kapselung von SetTimer. Waitable Timer sind genauer.

r2c2 1. Aug 2008 11:27

Re: Immer wiederkehrende Aufgaben realisieren
 
Zitat:

Zitat von RWarnecke
Diese Zeitverschiebung wie Ihr sie hier beschreibt, würde ja nur zustande kommen, wenn das Programm immer wieder aus dem Tray geholt wird und wieder zurück gelegt wird.

Nö. Die treten auch dann auf, wenn du in OnTimer den Timer immer aus und wieder anschaltest. Tust du das?

mfg

Christian

RWarnecke 1. Aug 2008 12:28

Re: Immer wiederkehrende Aufgaben realisieren
 
Zitat:

Zitat von r2c2
Nö. Die treten auch dann auf, wenn du in OnTimer den Timer immer aus und wieder anschaltest. Tust du das?

Nein, nicht im OnTimer. Lediglich nur dann wenn das Programm aus dem Tray kommt, wird es deaktiviert und wenn das Programm ins Tray gelegt wird, wieder aktiviert.

RWarnecke 7. Aug 2008 08:48

Re: Immer wiederkehrende Aufgaben realisieren
 
Ich habe da noch eine Frage, wenn ein TTimer schon läuft und ich dann Timer.Enabled := true setze, addiert sich dann die Zeit auch wieder ?

mkinzler 7. Aug 2008 08:49

Re: Immer wiederkehrende Aufgaben realisieren
 
Das Aktivieren eines Aktiven Vorgangs hat keine Auswirkung

RWarnecke 7. Aug 2008 10:59

Re: Immer wiederkehrende Aufgaben realisieren
 
Da bleibt mir ja nichts anderes übrig, als das über Waitable Timer zu lösen. :gruebel: Danke für die Infos.


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