Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Object-Pascal / Delphi-Language (https://www.delphipraxis.net/32-object-pascal-delphi-language/)
-   -   Delphi Problem mit StringList.SaveToFile im Thread (https://www.delphipraxis.net/54193-problem-mit-stringlist-savetofile-im-thread.html)

smudo 29. Sep 2005 14:11


Problem mit StringList.SaveToFile im Thread
 
Hallo :hi: ,

ich möchte das Loggen meiner Anwendung über einen Thread lösen.
Delphi-Quellcode:
//Schreibt den LogPuffer solange nicht mit DoStop abgebrochen wurde
procedure TLogThread.DoWait;
begin
  while (PStop=False) or          //eine Abbruchvariable
        (PLogPuffer.Count>0) do   //StringList enthält die zu loggenden Zeilen
  begin
    if (PLogPuffer.Count>0) then
    begin
      WriteLog(PLogPuffer[0]);    //schreibt eine Zeile <--hier knallts manchmal
      PLogPuffer.Delete(0);       //löscht diese Zeile
    end;
  end;
end;
In WriteLog wird wiederum eine StringList PLogs gefüllt. Sollte eine bestimmte Zeilenanzahl erreicht sein,
wird die erste Zeile gelöscht. --> enthält also nur die x aktuellsten Zeilen.
Letztendlich soll mit PLogs.SaveToFile die Liste der aktuellsten Logs gespeichert werden (die Liste wird also bei jedem Loggen komplett gespeichert) und dabei kommt es, wenn viele Log-Einträge schnell hintereinander geschrieben werden, ab und an zum Crash (Auf die Datei kann nicht zugegriffen werden).

Was passiert da und wie kann ich dem entgegenwirken? :gruebel:

Vielen Dank

René

Union 29. Sep 2005 15:20

Re: Problem mit StringList.SaveToFile im Thread
 
Zitat:

Zitat von smudo
Hallo :hi: ,

ich möchte das Loggen meiner Anwendung über einen Thread lösen.
Delphi-Quellcode:
//Schreibt den LogPuffer solange nicht mit DoStop abgebrochen wurde
procedure TLogThread.DoWait;
begin
  while (PStop=False) or          //eine Abbruchvariable
        (PLogPuffer.Count>0) do   //StringList enthält die zu loggenden Zeilen
  begin
    if (PLogPuffer.Count>0) then
    begin
      WriteLog(PLogPuffer[0]);    //schreibt eine Zeile <--hier knallts manchmal
      PLogPuffer.Delete(0);       //löscht diese Zeile
    end;
  end;
end;
In WriteLog wird wiederum eine StringList PLogs gefüllt. Sollte eine bestimmte Zeilenanzahl erreicht sein,
wird die erste Zeile gelöscht. --> enthält also nur die x aktuellsten Zeilen.
Letztendlich soll mit PLogs.SaveToFile die Liste der aktuellsten Logs gespeichert werden (die Liste wird also bei jedem Loggen komplett gespeichert) und dabei kommt es, wenn viele Log-Einträge schnell hintereinander geschrieben werden, ab und an zum Crash (Auf die Datei kann nicht zugegriffen werden).

Was passiert da und wie kann ich dem entgegenwirken? :gruebel:

Vielen Dank

René

Du musst Deine Threads synchronisieren. Schau mal nach unter Delphi-Referenz durchsuchenInitializeCriticalSection, [oh]DeleteCriticalSection,[/oh] Delphi-Referenz durchsuchenEnterCriticalSection, Delphi-Referenz durchsuchenLeaveCriticalSection.

smudo 29. Sep 2005 15:32

Re: Problem mit StringList.SaveToFile im Thread
 
Hallo Union,

vielen Dank schon wieder mal.
Deine Suchbegriffe konnte ich zwar nicht finden,
mir fiel dabei aber das Zauberwort Synchronize ein.
Einfach die DoWait-Methode mit Synchronize aufgerufen und schon kommt kein Fehler mehr.

Trotzdem weiß ich noch nicht, was vorher passierte. Hat sich der Thread selbst überholt?

Union 29. Sep 2005 15:36

Re: Problem mit StringList.SaveToFile im Thread
 
Zitat:

Zitat von smudo
Hallo Union,

vielen Dank schon wieder mal.
Deine Suchbegriffe konnte ich zwar nicht finden,
mir fiel dabei aber das Zauberwort Synchronize ein.
Einfach die DoWait-Methode mit Synchronize aufgerufen und schon kommt kein Fehler mehr.

Trotzdem weiß ich noch nicht, was vorher passierte. Hat sich der Thread selbst überholt?

Ganz Einfach, Thread 1 hat gerade WriteLog durchgeführt und will gerade Delete ausführen. Genau in der Millisekunde prüft Thread 2 mit Count > 0 und kommt noch in die Schleife, übergibt die Adresse von PLogBuffer an WriteLog... und in diesem Augenblick wird Delete ausgeführt. Dann zeigt die eben noch gültige Adresse ins Nirvana.

P.S. Die angegebenen Funktionen sind WINAPI-Funktionen.

smudo 29. Sep 2005 15:52

Re: Problem mit StringList.SaveToFile im Thread
 
Übrigens, :roll:

besser ist es, nicht DoWait schon mit Synchronize aufzurufen, sondern erst WriteLog.
Das verlangsamt den Thread zwar sehr, aber im ersten Fall kam es vor, dass das zu loggende Programm nicht mehr startete,
wahrscheinlich weil der Thread im Create des Formulars (vor dem Application.Run) gestartet wurde.
Schlussfolgere ich das richtig?

Union 29. Sep 2005 15:59

Re: Problem mit StringList.SaveToFile im Thread
 
Zitat:

Zitat von smudo
Übrigens, :roll:

besser ist es, nicht DoWait schon mit Synchronize aufzurufen, sondern erst WriteLog.
Das verlangsamt den Thread zwar sehr, aber im ersten Fall kam es vor, dass das zu loggende Programm nicht mehr startete,
wahrscheinlich weil der Thread im Create des Formulars (vor dem Application.Run) gestartet wurde.
Schlussfolgere ich das richtig?

Dur solltest die zu synchronisierenden Sektionen natürlich möglichst kurz halten. Es sollten also die zwei Zeilen (WriteLog, Delete) zu einer Sektion zusammengefasst werden. Oder Du erweiterst entsprechend WriteLog(blabla, bDelete). Und wenn bDelete = true wird gleich innerhalb der Funktion gelöscht.


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