![]() |
Nach Timer.Enable killt sich das Programm
Liebe Freunde.
Ich habe ein Programm geschrieben, das meine Heizung steuert. Seit 1997 läuft das Programm klaglaos, bis ich vor 6 Monaten die Pumpen- und Mischersteuerung ausgegliedert habe, und mit einer Siemens-LOGO durchführen lasse. Im Grunde genommen hat sich nicht viel geändert: - die Steuerbefehle für 4 Pumpen und 4 Mischer werden nicht mehr von der Steuerkarte in meinem PC ausgeführt. - Daten vom Heizkessel und von der PV werden von einem Server eingelesen - Die Abarbeitung Hauptschleife dauert nun anstatt 0,8sec. 1,3 sec. Zu Beginn der Regelung stoppe ich den Timer und am Ende starte ich ihn wieder, damit er die Hauptschleife nicht erneut auslöst. Der Timer löst jede Sekunde die Hauptschleife aus. Ich habe schon andere Timerkomponenten ausprobiert, was leider keinen Erfolg gebracht hat Mittlerweile habe ich zur Fehlersuche eine kleine Datenbank angelegt, die die Routinen vor dem Aufruf einträgt (siehe Bild) irgendwann -mal nach 40000 Einträgen, dann nach 6000 Einträgen beendet sich das Programm an einem Punkt, wo der Punkt Timer.enable:=true ausgeführt wird. Ich bin leider mit meiner Weisheit am Ende und hoffe, dass ich auf diesem Wege Ideen erhalte, die dieses Problem lösen. Vielleicht stehe ich auch nur auf dem Schlauch. Danke und lg Rupert
Delphi-Quellcode:
procedure THauptformular.Hauptschleife(Owner: TObject);
Begin inc (Hauptschleifencounter,1); if Hauptschleifencounter > 10 then Begin CounterStop(nil); inc(Regel_intervall_ist,1); if Regel_intervall_ist >= Regel_intervall then Begin // Abscannen der Raum- und Wassertemperaturen Digital_Messwerte_holen(nil); Analog_Messwerte_holen(nil); Pruefung_der_Vorprogrammierung(nil); // check auf einen Programmwechsel // Daten der Photovoltaik und des Heizkessels abfragen NANO_Daten_vom_Server(nil); Fronius_Daten_vom_Server(nil); Steuern[Kessel_Port]:=aus; Begin Regelvorgang_Raeume(nil); // Kesselbetrieb abfragen if ((not Heizung_ausflag)) then Abfrage_Kessel_Einschalten(nil); If ((not Winterbetrieb_Aktiv)) then Abfrage_Kessel_Ausschalten(nil); // nicht Abschalten, wenn Winterbetrieb Ausgeben_auf_Steuerungskarte(nil); Istwerte_aktualisieren(nil); // Speichern der aktuellen Werte zur Statistik inc(Speicherintervall_ist,1); if Speicherintervall_ist >= Speicherintervall then Begin Speicherintervall_ist:=0; Memo1.Clear; //memofeld entleeren um Speicherüberläufe zu verhindern Speicherung_Der_Messdaten(nil); end; //Speicherintervall end; // if Heizung_ausflag end; //Regel_intervall Display_aktualisieren(nil); CounterStart(nil); end; //if Hauptschleifencounter > 10 end; procedure THauptformular.Counterstop(Owner: TObject); Begin TimerEx1.Enabled:=False; end; procedure THauptformular.CounterStart(Owner: TObject); Begin TimerEx1. CleanupInstance; TimerEx1.Enabled:=True; end; |
AW: Nach Timer.Enable killt sich das Programm
Nach den Infos klingt das für mich komisch. Deine Hauptschleife wird jede Sekunde aufgerufen, dauert aber manchmal mehr als eine Sekunde.
Ich habe jetzt nicht dein Programm angeschaut, aber warum läßt du den Timer dann nicht alle 2 oder mehr Sekunden laufen, damit das Ende immer innerhalb der Zeit fertig ist? |
AW: Nach Timer.Enable killt sich das Programm
Halo,
laut Online Hilfe soll man CleanupInstance nicht direkt aufrufen. ![]() Gruß |
AW: Nach Timer.Enable killt sich das Programm
Zitat:
Was allerdings auffällt ist, dass der
Delphi-Quellcode:
nicht zurückgesetzt wird. Es wird also ab dem 10-ten Aufruf jedes mal der gesamte Zyklus durchlaufen. Ich weiß nicht, ob das so gedacht ist.
Hauptschleifencounter
|
AW: Nach Timer.Enable killt sich das Programm
Ich vermute auch das "CleanupInstance" da nicht hingehört, kommentiere das mal aus.
Statt den Timer immer wieder aus und ein zu schalten, ist es vieleicht besser die vergangene Zeit seit dem letzen Aufruf zu testen.
Delphi-Quellcode:
procedure Hauptschleife(Owner: TObject);
private SteuerungAktiv: Boolean; NextStart: TDateTime; procedure DoSteuerung; end; implementation const StartIntervall = 1{s} /24/60/60; Startverzoegerung = 10{s} /24/60/60; function NowUTC: TDateTime; var SystemTime: TSystemTime; begin GetSystemTime(SystemTime); Result := SystemTimeToDateTime(SystemTime); end; procedure THauptformular.Hauptschleife(Owner: TObject); begin if not SteuerungAktiv then begin SteuerungAktiv := True; if NowUTC >= NextStart then begin NextStart := NextStart + StartIntervall; // alternativ NowUTC + StartIntervall DoSteuerung; end; SteuerungAktiv := False; end; end; procedure THauptformular.Counterstop(Owner: TObject); Begin TimerEx1.Enabled:=False; end; procedure THauptformular.CounterStart(Owner: TObject); Begin NextStart := NowUTC + Startverzoegerung; TimerEx1.Enabled:=True; end; |
AW: Nach Timer.Enable killt sich das Programm
Zitat:
Wird remarkt - Danke! |
AW: Nach Timer.Enable killt sich das Programm
Zitat:
Die Regelintervalle sind 20 sec. damit die Mischermotoren nicht dauernd auf/zu fahren. Deren Gesamtlaufzeit ist 140 sec. Die Sericherintervalle sind 30 x Regelintervall also 600 sec. der Hauptschleifencounter wird auf 0 gesetzt - habe ich beim Löschen der Kommentierung (wegen der Lesbarkeit des Codes) versehentlich mitgelöscht - sorry - aber danke, würde ohne Nullsetzung nicht funktionieren. Hat sich von gestern auf heute nach 33142 Ereignissen wieder gekillt - an der selben Stelle. Habe CleanupInstance entfernt und nach inc (Hauptschleifencounter,1); einen Eintrag in die Datenbank gesetzt, um zu sehen, ob der Timer die Hauptschleife auslöst oder er selbst den Kill auslöst. SW neu gestartet. Danke für die Tipps!
Delphi-Quellcode:
Ausgeben_auf_Steuerungskarte(nil);
Hauptschleifencounter:=0; Istwerte_aktualisieren(nil); |
AW: Nach Timer.Enable killt sich das Programm
Hallo,
was sagt denn FastMM4 zu Deinem Programm? Ansonsten, wie schon gesagt wurde, mal den Taskmanager mitlaufen lassen zwecks Kontrolle des Speichers und der Handles. |
AW: Nach Timer.Enable killt sich das Programm
Zitat:
Taskmanager läuft bereits mit. |
AW: Nach Timer.Enable killt sich das Programm
Liste der Anhänge anzeigen (Anzahl: 1)
Zitat:
In der Statuszeile werden die jeweiligen "Stationen" - was soeben durchgeführt wird - visualisiert. Werde ich beim nächsten Crash auf 2 sec. erhöhen und testen. Führt m.e. jedoch nicht zum Verursacher des Problems, wäre aber vlt. eine Lösung - Danke! ![]() |
AW: Nach Timer.Enable killt sich das Programm
Du kannst dir in FastMM auch live anzeigen was so im Speicher passiert. Dazu findest du im FastMM4 Ordner auch eine Demo, deren Formular du einfach einbinden kannst. Die liegt unter: FastMM\Demos\Usage Tracker
Das hilft in solchen Fällen oft mehr als nur die Leckanzeige beim Beenden des Prozesses. |
AW: Nach Timer.Enable killt sich das Programm
Liste der Anhänge anzeigen (Anzahl: 1)
Heute um 5:56 passierte zum Zeitpunkt TimerEx1.Enable:=true folgendes:
Zitat:
Zitat:
Es ist aber absolut sicher, dass durch das Starten des Timers der Fehler ausgelöst wird (siehe Bild). Die Fragen sind: - Gibt es eine andere Möglichkeit - ohne Timer - dei Hauptschleife zyklisch durchlaufen zu lassen - Wie findet man einen kernel32-Fehler, der praktisch alles sein kann Das habe ich in einem US-Forum gefunden und werde es probieren: Zitat:
![]() |
AW: Nach Timer.Enable killt sich das Programm
.. hast Du madExcept zur Verfügung?
Mit den madExcept Daten ist oftmals einfacher den Grund einer Exception zu ergründen. Grüße Klaus |
AW: Nach Timer.Enable killt sich das Programm
Zitat:
SetTimer, KillTimer Zitat:
Thread, CreateWaitableTimer, WaitForSingleObject, PostThreadMessage usw.. |
AW: Nach Timer.Enable killt sich das Programm
Wenn ich tief in meine Glaskugel schau, hab ich diese Hypothese:
Direkte Fehlerursache ist ein Überlauf des Aufrufstapels. Wenn der Timer im OnTimer-Ereignis wieder angeschalten wird, wird an dieser Stelle möglicherweise OnTimer sofort wieder aufgerufen. So dass Hauptschleife() sich indirekt selbst rekursiv aufruft, immer wieder, bis der Stapel überläuft. Ein Tool wie madExcept könnte da Klarheit schaffen. Alternative zum Ab- und Anschalten des Timers hab ich weiter oben gepostet. Du müsstest halt mal probieren ob das hilft. |
AW: Nach Timer.Enable killt sich das Programm
Zitat:
Die Schleife dauert halt nun 30 sec., aber wenn's hilft ;) |
AW: Nach Timer.Enable killt sich das Programm
Zitat:
Ich vermute, der Fehler ist unabhängig von dem Timer. |
AW: Nach Timer.Enable killt sich das Programm
Zitat:
Zitat:
Delphi-Quellcode:
procedure THauptformular.Hauptschleife(Owner: TObject);
var zaehler: shortint; Begin begin inc (Hauptschleifencounter,1); Ereignis_notieren('HS 1. Start Hauptschleife - '+inttostr(Hauptschleifencounter)); SchleifenBar.position:=11-Hauptschleifencounter; .... Display_aktualisieren(nil); CounterStart(nil); end; //if Hauptschleifencounter > 10 end; // **** **** **** **** **** **** **** **** **** **** procedure THauptformular.CounterStart(Owner: TObject); Begin Ereignis_notieren('--- TimerEx1.Enabled:=True'); TimerEx1.Enabled:=True; end; |
AW: Nach Timer.Enable killt sich das Programm
Liste der Anhänge anzeigen (Anzahl: 1)
Zitat:
madExcept ist seit heute implementiert ![]() |
AW: Nach Timer.Enable killt sich das Programm
Liste der Anhänge anzeigen (Anzahl: 3)
Keine Mitteilung von madExcept. Nichts...
Auffällig ist, dass die letzte Eintragung immer der Timerist und der Crash stets um 5:56 bzw. 5:58 passiert. ![]() ![]() ![]() |
AW: Nach Timer.Enable killt sich das Programm
Ist madExcept auch richtig installiert und in die Anwendung eingebunden?
Erzeuge zum Test mal eine Exception in deiner Methode und schau ob und wie diese gemeldet wird.
Delphi-Quellcode:
raise Exception.Create('Test');
|
AW: Nach Timer.Enable killt sich das Programm
Natürlich wurde MadExcept richtig installiert und auch zuvor getestet
Aufgrund der unterschiedlichen Meinungen zu diesem Problem bin ich mir aber ziemlich sicher, dass es kein Programmfehler ist. Zitat:
|
AW: Nach Timer.Enable killt sich das Programm
Die Meldung sagt ja aber schon, dass es ein eindeutig Programmfehler ist ;)
Da wird der mögliche Fehlerfall, dass die Datei anderweitig geöffnet ist, nicht behandelt. Wenn es immer die gleiche Zeit ist: findet zu dieser Zeit evtl. ein Backup statt? Es gibt ja durchaus berechtigte Interessen dritter Programme bzw. des Betriebssystems - sei es ein Backup, ein gründlicher AV-Scan, ... . Da muss man dann schauen, ob man die Datei dauerhaft offen hält (und auf teilweise sinnvollen Fremdzugriff wie eben ein Backup verzichtet), oder ob man den Fehlerfall behandelt (was man so oder so muss, da die Datei auch schon beim ersten Öffnen anderweitig gesperrt sein kann). |
AW: Nach Timer.Enable killt sich das Programm
Zitat:
Suf duesem Computer läuft nichts. Kein Backup, kein Virenscanner. |
AW: Nach Timer.Enable killt sich das Programm
Timer werden in fast jeder Anwendung verwendet.
Kommentiere doch mal alles was mit deiner Steuerung zu tun hat aus. Dann lass das Programm laufen und schau ob der Fehler noch auftritt. |
AW: Nach Timer.Enable killt sich das Programm
Zitat:
Das wird diese Woche nicht mehr gehen, aber ab Montag kann ich das probieren. Danke! |
AW: Nach Timer.Enable killt sich das Programm
[QUOTE=Rupert;1494313]
Zitat:
Zitat:
"Timen" kann man dann immer noch mit WaitForSingleObject mit definiertem Timeout auf ein Terminate-Event, um die Schleife im Falle des Programmschließens sofort zu beenden. Ansonsten, um einen Mehrfachaufruf der Timer-Methode wirklich zu verhindern: mit TCriticalSection wrappen, dann kann er nicht nochmal rein, bevor er raus ist. Ansonsten hilft es manchmal auch schon, die Logik nicht in der Timer-Methode zu haben, sondern von dort per PostMessage an eine andere Methode die eigentliche Ausführung zu triggern. |
AW: Nach Timer.Enable killt sich das Programm
|
AW: Nach Timer.Enable killt sich das Programm
TCriticalsection hält nur andere Threads davon ab den selben Codeblock aufzurufen.
Innerhalb eines Threads ist der Mehrfachaufruf möglich, deshalb ist das hier keine Option. Dafür reicht eine Variable, wie oben von mir vorgeschlagen. Normalerweise würde man eine Steuerung die Tag und Nacht läuft auch nicht auf dem PC implementieren. Dafür ist zum Beispiel Arduino besser geignet: ![]() Der PC oder das Smartfone zeigt dann im einfachsten Fall nur die Webseite des Controllers an, über die man das Programm steuert. |
AW: Nach Timer.Enable killt sich das Programm
Zitat:
In diesem Kontext eine Zwischenfrage: verwendet das Programm zufälligerweise Application.ProcessMessages? Das wird ja gerne mal reingehauen, wenn man den UI-Thread viel arbeiten lässt, und hat bei mir schnell dahingerotzten Timerdingern auch schonmal was kaputtgemacht, bevor ich gelernt habe, die Finger davon zu lassen. Deswegen ja auch der Tipp, die eigentliche Funktionalität per PostMessage in ner anderen Methode zu triggern, um aus dem Kontext dieser vom Timer aufgerufenen Methode rauszukommen. Zitat:
|
AW: Nach Timer.Enable killt sich das Programm
Liste der Anhänge anzeigen (Anzahl: 3)
Zitat:
Zitat:
Die Bilder sollen ein wenig den Umfang erkennen lassen. Wichtig war schon immer der remote Zugriff, weil wir zwei Ferienwohnungen haben, und die Heizung entsprechend aktivieren/deaktivieren. -es war von Anfang an Delphi 4 und dann 5 ![]() ![]() ![]() |
AW: Nach Timer.Enable killt sich das Programm
Ich glaube, die Ursache gefunden zu haben.
Die Software läuft nämlich seit Samstag Abend fehlerfrei. Was habe ich geändert? Es gibt 3 Variable, die in der Hauptschleife verändert werden. Hauptschleifencounter, Regel_intervall_ist und Speicherintervall_ist. Alle drei habe ich, zurück wie bisher, auf Integer geändert. Ich hatte sie - fragt nicht was mich geritten hat - auf Shortint geändert, da sie ohnedies nur bis max. 60 zählen. Nachdem ich protokolliere, was ich alles geändert habe, kam ich (während meines Urlaubs) auf die Idee, alle neuen Änderungen der Reihe nach wieder zurückzustellen. Am Samstag abend habe ich dann über den VPN-Zugriff auf meinen PC neu compiliert und die Software auf den Heiz-PC übertragen - seither läuft sie unentwegt. Ich hoffe, dass dies der Fehler gewesen ist, da die weiteren Änderungen die Photovoltaik-Daten und die Heizkessel-Daten betreffen und dort wurden die Schleifen stets korrekt abgearbeitet. Warum ein Shortint zu einem Fehler führt - keine Ahnung, da die Variablen niemals unter 0 oder über 61 gehen. Aber egal - ich schließe den Thread aber noch nicht - wer weiß... Vielen Dank für die Tipps, die immerhin zur Eingrenzung geführt haben :wink: |
AW: Nach Timer.Enable killt sich das Programm
Zitat:
Vielleicht ist das eine Ursache. |
AW: Nach Timer.Enable killt sich das Programm
Mit "killt sich das Programm" ist doch ein Absturz gemeint?
Die Beschreibung hört sich aber jetzt eher nach eine Festhängen in einer Endlosschleife an. Hauptschleifencounter wird bei jedem Aufruf des Timers erhöht, aber scheinbar niemals zurück gesetzt. Natürlich läuft der irgendwann über und wird negativ. Dann dauerrt es natürlich ewig bis der wieder positiv und größer 10 wird. Im Prinzip könnte das auch mit Integer passieren, dauert halt 65000 mal so lange. |
AW: Nach Timer.Enable killt sich das Programm
Zitat:
![]() |
AW: Nach Timer.Enable killt sich das Programm
Liste der Anhänge anzeigen (Anzahl: 3)
Neue Erkenntnisse:
Also die Variablen habe ich vorerst nicht als Verursacher des Absturzes isolieren können. Deshalb habe ich nun den Processmonitor mitlaufen lassen und dabei festgestellt, dass der Absturz ähnlich damit ist, als würde jemand den Menüpunkt "Beenden" klicken. Ähnlich deshalb, weil nach dem Processname 17:56:11 1087389 (CloseFile) noch Dinge geschehen, die beim manuellen "Beenden" vom Monitor nicht aufgezeichnet wurden. Heute um 17:56:11 war es so weit. (siehe Logfile-1.txt) Wenn man das "X" rechts oben klickt, sieht dass Ende des Programms wie in Logfile-2.txt aus und beende ich das Programm mit dem Menüpunkt "Beenden" dann ist es identisch mit dem "X"-Click - siehe "Logfile-3.txt". Resumeé: Beim normalen Beenden des Programms oder dem "X" ist nach 4 Zeilen Schluss mit allem. Verabschiedet sich das Programm, dann werden noch hinterher die Datenbanken geschlossen (Heizdaten.abs und Fehlersuche.abs) wie man sehen kann. Kein Remote-Acccess, der mir einen "Streich" spielen würde: Der "Windows-Remote-Access" ist deaktiviert - auch den "VNC-Access" habe ich deaktiviert. Der Heiz-PC hat in der Cisco-ASA eine Sperre, damit er nicht ins Internet kann - nur NTC wird durchgelassen. Auch passieren keine TCP-Aktivitäten, das würde der Syslog aufzeichnen. Ich blick`nicht durch, was da in der Software vorgeht... ![]() ![]() ![]() |
AW: Nach Timer.Enable killt sich das Programm
Zitat:
Absturz:
Code:
Regulärer Exit:
ReadFile Datenbank.xyz
Thread Exit Process Exit CloseFile Aktueller Ordner CloseFile Datenbank.xyz
Code:
Merkst du den Unterschied? Beim Absturz werden die Dateihandles erst nach dem Beenden des Prozesses automatisch durch Windows aufgeräumt. Beim regulären Beenden macht das Programm das vorher.
ReadFile Datenbank.xyz
CloseFile Datenbank.xyz Thread Exit Process Exit CloseFile Aktueller Ordner Der Fehler könnte beim Zugriff auf die Fehlersuche.abs oder in den Events davor (die hier nicht dabei sind) passiert sein. |
AW: Nach Timer.Enable killt sich das Programm
Zitat:
|
AW: Nach Timer.Enable killt sich das Programm
Liste der Anhänge anzeigen (Anzahl: 2)
Ich finde absolut nichts...
hier sind die letzten 2 Sekunden vor dem Ende "Process Profiling" in Heizung2020.exe ist der Timer, und ist das letzte Ereignis vor dem Absturz. Der Absturz passierte um 17:49:21. vlt. sieht jemand etwas anhand der beiden Logfiles. Logfile6-10-21-a.txt ist nur der Log von Heizung0202.exe, Logfile6-10-21-alles.txt beinhaltet auch die anderen Programme. ![]() ![]() |
AW: Nach Timer.Enable killt sich das Programm
Findest Du dazu
Code:
was im Ereignislog?
"17:49:21,6079279","Heizung2020.exe","1016","Process Exit","","SUCCESS","Exit Status: -1073741819, User Time: 1496.0712448 seconds, Kernel Time: 526.5471376 seconds, Private Bytes: 17.899.520, Peak Private Bytes: 22.761.472, Working Set: 21.819.392, Peak Working Set: 26.808.320"
Ansonsten Suchmaschine Deiner Wahl mal mit exit status -1073741819 füttern. Meine behauptet, es gäbe rund 48.300.000 Ergebnissen. Keine Ahnung, wie man das jetzt noch sinnvoll für Deine konkrete Problematik eingrenzen kann. Es scheint aber ein grundsätzliches Problem für diverse Software zu sein, das zuweilen auftreten kann. Hexadezimal entspricht -1073741819 = FFFFFFFFC0000005 Der Betriebssystemhersteller meint dazu: Zitat:
|
Alle Zeitangaben in WEZ +1. Es ist jetzt 02:34 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