![]() |
AW: Programm stürzt nach mehren Stunden Laufzeit ab.
Zitat:
|
AW: Programm stürzt nach mehren Stunden Laufzeit ab.
Beispiel 3:
Delphi-Quellcode:
Bezüglich des korrekten Hinweises von TomF zur Position des
var
ts : tstringlist; begin ts := tstringlist.create; try try mach das 1 mach das 2 mach das 3 except on e : Exception do begin MessageDlg(e.Message,mtError,[mbOk],0); // oder eine beliebige, aber garantiert funktionierende Variante der Fehlerprotokollierung. // aber nie ein -- wie venice2 schon sagt: // // Sorry eine leere Fehlerbehandlung ist ein Nonsens. // // bei einem Fehler wird nichts gemacht. fährt aber nach except weiter? <-- Wenn das nicht klar ist, ist das zu verifizieren. // // Es ist immer sinnvoll zu wissen, ob an einer Stelle Fehler auftreten oder nicht. // Insbesondere dann, wenn nach nichtlokalisierbaren Fehlern gesucht wird. // Du hast schon ein Addline_Debug(Format('Nachvollziehbare Angabe zum Fehlerort: %s',[e.Message])); // Dann nutze es auch ;-) end; end; finally ts.free; end; end;
Delphi-Quellcode:
Kompilerwarnungen sind zu beachten und die Ursachen der Warnungen zu beheben, die kommen nicht "zum Spass". Es sind oft Kleinigkeiten, aber die summieren sich im Laufe von Stunden und momentan blickt niemand so recht, wo genau die Ursache des Problemes liegen könnte, mit dem Du Dich gerade rumschlagen musst. In so 'nem Fall kann Pingeligkeit durchaus zielführend sein ;-)
ts:=tstringlist.create;
|
AW: Programm stürzt nach mehren Stunden Laufzeit ab.
Zitat:
Wie es mit dem Speicher aussieht darüber gab es noch keine Information. Aber gut zusammen geschustert. :thumb: |
AW: Programm stürzt nach mehren Stunden Laufzeit ab.
Zitat:
Aber warum sie sich aufsummieren ist (zumindest mir) bisher nicht klar geworden. Meiner Meinung nach kennen wir eine Folge eines Fehlers (oder möglicherweise mehrerer Fehler?), aber noch nicht die Ursache(n) ;-) |
AW: Programm stürzt nach mehren Stunden Laufzeit ab.
Zitat:
Du siehst es aber Richtig. Glaskugel :glaskugel: haben wir leider nicht. Warten wir mal was da noch so kommt. |
AW: Programm stürzt nach mehren Stunden Laufzeit ab.
Anscheinend verstehe ich ziemlich viel nicht. :oops:
Beispiel 3 habe ich ebenfalls im Internet in einem toutorial geshen und habe nun begonnen dies so abzuändern. Da es wohl so einfach richtig ist :) Weshalb aber soll/muss
Delphi-Quellcode:
vor den
ts:=tstringlist.create;
Delphi-Quellcode:
stehen? Was wäre der nachteil wenn es nach dem try steht? Grössere ressourcen verbrauch? Oder unübersichtlicher da man bei einer exception mehr zu kontrollieren hat?
try
Ich bin am mittwoch wieder am arbeiten. Dann werde ich alles nach besten wissen und gewissen abändern und euch genauere infos über speicherverbrauch und handles geben können. In meinem ersten Post ist der komplette quelltext! |
AW: Programm stürzt nach mehren Stunden Laufzeit ab.
Zitat:
Du arbeitest sehr viel mit globalen Variabel, das macht den Quelltext nicht unbedingt leichter les- und verstehbar. Mir ist z. B. noch nicht so ganz klar geworden, wann ts_log nun von wo welche Daten bekommt, wann sie wo unter welchen Bedingungen in die Datei geschrieben werden, ob und ggfls. wann und wie lange ts_log und Memo_log (teilweise) identischen Inhalt haben ... Viele Deiner Prozeduren könntest Du auch zu Prozeduren des Formulars machen, dann sparst Du Dir schonmal die vielen Form1... Wahllos rausgegriffen mit der Bitte um "grundsätzliche" Korrektur:
Delphi-Quellcode:
Lieber in dieser Form:
if tdirectory.exists(programmpfad+'LS')=false then tdirectory.CreateDirectory(programmpfad+'LS');
if tdirectory.exists(programmpfad+'RE')=false then tdirectory.CreateDirectory(programmpfad+'RE'); if tdirectory.exists(programmpfad+'ET1')=false then tdirectory.CreateDirectory(programmpfad+'ET1'); if tdirectory.exists(programmpfad+'ET2')=false then tdirectory.CreateDirectory(programmpfad+'ET2'); if form1.CheckBox_autostart.checked=true then form1.Button_start_action.Click; ... if ts.Strings[14]='tray:off' then form1.CheckBox_tray.Checked:=false; if ts.Strings[15]='autostart:off' then form1.CheckBox_autostart.Checked:=false; if ts.Strings[16]='debug:off' then form1.CheckBox_DebugLog.Checked:=false; if ts.Strings[17]='hidecmd:off' then form1.CheckBox_verstecke_cmd.Checked:=false; ... if form1.CheckBox_tray.Checked=false then ts.Add('tray:off') else ts.Add('tray:on'); if form1.CheckBox_autostart.Checked=false then ts.Add('autostart:off') else ts.Add('autostart:on'); if form1.CheckBox_DebugLog.Checked=false then ts.Add('debug:off') else ts.Add('debug:on'); if form1.CheckBox_verstecke_cmd.Checked=false then ts.Add('hidecmd:off') else ts.Add('hidecmd:on'); ... if form1.idftp1.DirectoryListing[i].FileName='.'=false then if form1.idftp1.DirectoryListing[i].FileName='..'=false then begin
Delphi-Quellcode:
Und nein: Da ist jetzt kein Muss, sondern nur als Idee für die eventuelle, zukünftige Beachtung gedacht.
if not tdirectory.exists(programmpfad + 'LS') then tdirectory.CreateDirectory(programmpfad + 'LS');
if not tdirectory.exists(programmpfad + 'RE') then tdirectory.CreateDirectory(programmpfad + 'RE'); if not tdirectory.exists(programmpfad + 'ET1') then tdirectory.CreateDirectory(programmpfad + 'ET1'); if not tdirectory.exists(programmpfad + 'ET2') then tdirectory.CreateDirectory(programmpfad + 'ET2'); if form1.CheckBox_autostart.checked then form1.Button_start_action.Click; ... form1.CheckBox_tray.Checked := ts.Strings[14] = 'tray:on'; form1.CheckBox_autostart.Checked := ts.Strings[15] = 'autostart:on'; form1.CheckBox_DebugLog.Checked := ts.Strings[16] = 'debug:on'; form1.CheckBox_verstecke_cmd.Checked := ts.Strings[17] = 'hidecmd:on'; ... ts.Add(IfThen(form1.CheckBox_tray.Checked,'tray:on','tray:off')); ts.Add(IfThen(form1.CheckBox_autostart.Checked,'autostart:on','autostart:off')); ts.Add(IfThen(form1.CheckBox_DebugLog.Checked,'debug:on','debug:off')); ts.Add(IfThen(form1.CheckBox_verstecke_cmd.Checked,'hidecmd:on','hidecmd:off')); ... if (form1.idftp1.DirectoryListing[i].FileName <> '.') and (form1.idftp1.DirectoryListing[i].FileName <> '..') then begin Und vermutlich haben andere dazu auch andere Ansichten. |
AW: Programm stürzt nach mehren Stunden Laufzeit ab.
Zitat:
Deine Vorschläge sind sicher viel korrekter als meine daher werde ich sie am Mittwoch alle abändern und hoffe das ich dann in Zukunft daran denke werde und es dann auch zum "Standart" für mich wird. Beim Log habe ich mir folgendes überlegt: Grundsätzlich wird das Memo einfach immer und immer wieder abgespeichert. (procedure addline und addline_debug) wenn aber mehr als 5000 zeilen im memo sind, wird wenn vorhanden die Log_old.txt geladen (in die TS_Log) und die zeilen des memo werden hinzugefügt. (sofern die Log_old.txt (also ts_log) nicht bereits mehr als 20'000 zeilen hat). Es ging mir einerseits darum das memo möglichst schnell speichern zu können. (weniger als 5000 zeilen) anderrerseits darf das "komplette" Log (also log_old.txt) nicht zuviel Speicherplatz verbraten. daher auch da nochmals die begrenzung von 20'000 Zeilen. Sicher auch nicht die perfekte Lösung. aber eigentlich sollte auch nicht viel im log stehen da Addline_Debug normalerweise deaktiviert ist. und Addline vieleicht 1-2x pro tag ein eintrag macht betreffend: Verbindungsproblem zum server (warum auch immer... zB wlan verbindung abgerissen, Server Down, oder sonstiges. ) |
AW: Programm stürzt nach mehren Stunden Laufzeit ab.
Prinzipiell deckt sich Deine Beschreibung mit meiner Vermutung für das gedachte Vorgehen. Nur bin ich mir nicht sicher, ob es auch so funktioniert :-(
Delphi-Quellcode:
Versuch einer Korrektur:procedure addline (s: string); var i : integer; begin try form1.Memo_Log.Lines.Add(datetimetostr(now)+': ' + s); if form1.Memo_Log.Lines.Count > 5000 then begin // Wenn form1.Memo_Log.Lines mal über 5000 Zeilen hatte, kann diese Datei existieren. if tfile.Exists(programmpfad + 'log_OLD.txt') then begin // Wir laden sie dann. ts_log.loadfromfile(programmpfad+'log_OLD.txt'); // Sollte sie mehr als 20000 Zeilen enthalten, if ts_log.Count > 20000 then begin // schmeißen wir den Inhalt weg ts_log.Clear; // und fangen neu an. ts_log.Add(Datetimetostr(now)+' Altes Log wurde automatisch zurückgesetzt da über 20 000 zeilen.') end; // Dann hängen wir den Inhalt von form1.Memo_Log.Lines an for I := 0 to form1.Memo_Log.Lines.Count-1 do ts_log.Add(form1.Memo_Log.Lines[i]); // und haben das alles im Speicher. end; // Memo hat mehr als 5000 Zeilen, dann schreiben wir das in log_OLD.txt // und überschreiben damit die Datei, die wir gerade eben mit ts_log.loadfromfile geladen haben. form1.Memo_Log.Lines.SaveToFile(programmpfad + 'log_OLD.txt'); // und schmeißen unseren Memo-Inhalt weg. form1.Memo_Log.Clear; // Damit kann log_OLD.txt immer nur maximal den Inhalt von einem form1.Memo_Log.Lines haben. // Da ts_log nie gespeichert wird, halten wir alles, was per ts_log.Add(form1.Memo_Log.Lines[i]); // hinzugefügt wird, immer nur im Speicher vor. Da man die Stringlist aber eh nicht sehen kann // könnte man darauf auch verzichten :-( end; form1.Memo_Log.Lines.SaveToFile(programmpfad+'log.txt'); except on e:exception do form1.Memo_Log.Lines.Add('Fehler beim speichern des Log Files: '+e.Message); end; end;
Delphi-Quellcode:
Da Addline_Debug eigentlich genau das Gleiche macht, kann man da ja eventuell mal ein bisserl was an (redundantem) Quelltext sparen:
procedure addline(s: string);
var ts_log : TStringList; // Es gibt keinen Grund, warum wir hierfür eine globale Stringliste nehmen sollten // und deren Inhalt immer im Speicher halten sollten. begin ts_log := TStringList.Create; try try form1.Memo_Log.Lines.Add(Format('%s: %s',[datetimetostr(now),s])); if form1.Memo_Log.Lines.Count > 5000 then begin // Wenn form1.Memo_Log.Lines mal über 5000 Zeilen hatte, kann diese Datei existieren // und wir laden sie. if tfile.Exists(programmpfad + 'log_OLD.txt') then ts_log.loadfromfile(programmpfad + 'log_OLD.txt'); // Sollte sie mehr als 20000 Zeilen enthalten, if ts_log.Count > 20000 then begin // schmeißen wir den Inhalt weg ts_log.Clear; // und fangen neu an. ts_log.Add(Format('%s: %s',[Datetimetostr(now),'Altes Log wurde automatisch zurückgesetzt da über 20 000 Zeilen.'])); end; // Dann hängen wir den Inhalt von form1.Memo_Log.Lines an, das geht auch am Stück und nicht nur zeilenweise. ts_log.AddStrings(form1.Memo_Log.Lines); // und speichern es in der Datei ts_log.SaveToFile(programmpfad + 'log_OLD.txt'); // form1.Memo_Log wird geleert. form1.Memo_Log.Clear; // und hängen die Meldung, die zum Aufruf von AddLines führte an. // Andernfalls bekämen wir grundsätzlich jede 5001. Meldung (im Memo) nie zu Gesicht. form1.Memo_Log.Lines.Add(Format('%s: %s',[datetimetostr(now),s])); end; form1.Memo_Log.Lines.SaveToFile(programmpfad + 'log.txt'); except on e:exception do begin form1.Memo_Log.Lines.Add('Fehler beim Speichern der Logfiles: ' + e.Message); end; end; finally ts_log.free; end; end;
Delphi-Quellcode:
Das ist jetzt nur hingedaddelt, keine Ahnung, ob es jetzt wirklich das macht, was ursprünglich angedacht war.
procedure Addline_Debug(s : String);
begin if form1.CheckBox_DebugLog.Checked then AddLine(Format('(Debug) %s',[s])); end; |
AW: Programm stürzt nach mehren Stunden Laufzeit ab.
Also ich habe heute versucht den Code anzupassen.
Im Anhang noch ein Bild des Taskmanager betreffend Speicherauslastung. Und ein Auszug des Log aus dem Programm. Die Handles zählen sich hoch aber reduzieren sich dann zum teil auch wieder. Ich weiss jetzt gar nicht genau ob dies gut / schlecht ist. Richtig testen werde ich morgen im Geschäft können. Speicher Screenshot aus Taskmanager ![]() Delphi Code angepasst: ![]() Log aus Programm ![]() |
Alle Zeitangaben in WEZ +1. Es ist jetzt 01:18 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