Pascal/Lazarus Fehler beim Lesen aus *einer* Textdatei bei Mehrfach-Programmstart

jrx

Mitglied
Hallo zusammen.
Ich greife in meinem Programm auf Daten einer Textdatei zu.

Code:
if FileExists('file.txt') then begin
    s:=Tstringlist.Create;
    s.LoadFromFile('file.txt');
    //  Machwas mit S
   ...
    s.Destroy;
end;

Das funktioniert eigentlich ganz normal.
Wenn ich das Programm aber mehrmals, gleichzeitig/schnell hintereinander starte, dann stürzen manchmal einige der gestarteten Programme mit dem Fehlerfenster, das aus der Datei nicht zu lesen sei, ab.

Ich bin eigentlich der Meinung, daß die Datei-Zugriffe innerhalb der Bibliotheken abgesichert sind. Außerdem will ich ja nur lesen. Nach s.LoadfromFile sollte alles, was mit dem file zu tun hat, eigentlich erledigt sein (z.B. Datei geschlossen).

Woran kann es denn liegen?
Vielleicht bitte mit etwas Code, wie man den Fehler abfangen kann (a lá "procedure WarteBisFileFreiIst('file.txt') ;")

Vielen Dank.
jrx
 

deepthroat

Erfahrenes Mitglied
Hi.

Ich habe keine Ahnung von Pascal direkt (ist schon sehr lange her).

Grundsätzlich ist unter Windows (du benutzt doch Windows?) das Problem, das Programme nicht gleichzeitig auf bereits geöffnete Dateien zugreifen können.

Du müßtest das Öffnen bzw. Laden einfach probieren und wenn es fehlschlagt aufgrund eines SHARING Fehlers, dann kurz warten und es einfach nochmal versuchen.

Pascal hat doch try catch Anweisungen, oder?!

Gruß
 

jrx

Mitglied
Hallo,

Ja ich schreibe für Windows (XP).

Hier meine, zugegebenermaßen etwas unglückliche Lösung.
Zum Glück ist der Fehler in meinem Programm eher kosmetischer Natur.
Wenn in meiner Settingsdatei keine Daten gefunden werden, verwendet das Programm sinnvolle Defaults.
Allerdings wird ja in den Quellen für LoadFromFile schon eine try ... finally Abfrage gemacht.
Deshalb finde ich es ja nun DoppelGemoppelt.

Code:
 if FileExists('file.txt') then begin
    s:=Tstringlist.Create;
    try
       s.LoadFromFile('file.txt');
    except
       s.text:='error';
    end;
    //  Machwas mit S
   ...
    s.Destroy;
end;

Wenn ich nun eventuell im Except auf einen Programmpunkt vor try springen würde, riskiere ich Spaghetti-Code und fange mir vielleicht eine Endlosschleife ein, wo ich Abbruchkriterien definieren muß...

Vielleicht kennt ja noch jemand eine elegante Lösung für mein Problem.
jrx
 

deepthroat

Erfahrenes Mitglied
Hi.

Die grundsätzliche Vorgehensweise ist diese:
Code:
tries := 0
maxRetries := 20

repeat
  try
     ...
     break
  except
    on ErrorSharingViolation do Sleep 100ms; tries := tries + 1
    else raise
  end
until tries >= maxRetries
Siehe auch http://support.microsoft.com/kb/316609/de

Du mußt also 1) du Anzahl der Versuche auf ein Maximum begrenzen und 2) sicherstellen, das es sich bei dem Fehler um eine ErrorSharingViolation bzw. keinen fatalen Fehler handelt (ich weiß nicht wie du an die genaue Fehlerursache kommst, evlt. hat die Ausnahme eine Eigenschaft dafür).

Gruß
 
Zuletzt bearbeitet:
  • Gefällt mir
Reaktionen: jrx