Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Object-Pascal / Delphi-Language (https://www.delphipraxis.net/32-object-pascal-delphi-language/)
-   -   Delphi Frage zu mehreren Try's (https://www.delphipraxis.net/71755-frage-zu-mehreren-trys.html)

Stefan Hueg 20. Jun 2006 18:06


Frage zu mehreren Try's
 
Ich stehe nun vor folgendem Problem, konnte bisher keine befriedigende Antwort dazu finden.

Szenario:
Ich will eine Ini-Datei öffnen, aus ihr irgendwas lesen und diese dann wieder freigeben. Falls währenddessen irgend ein Fehler auftritt soll eine Fehlermeldung ausgegeben werden.

Nun, eigtl. nicht schwierig. Aber es gibt mehrere Lösungsansätze und ich würde gerne wissen welcher der eleganteste bzw. Optimalste ist.

Beispiel 1:
Delphi-Quellcode:
procedure LoadIni(Filename: String);
var
  FileSettings: TIniFile;
  Test: String;
begin
  try
    try
      FileSettings := TIniFile.Create(Filename);
      Test := FileSettings.ReadString('Test', 'Test', 'Test');
    except on E: Exception do
      ShowMessage('Fehler');
    end;
  finally
    FileSettings.Free;
  end;
end;
Beispiel 2:
Delphi-Quellcode:
procedure LoadIni(Filename: String);
var
  FileSettings: TIniFile;
  Test: String;
begin
  try
    FileSettings := TIniFile.Create(Filename);
    Test := FileSettings.ReadString('Test', 'Test', 'Test');
    FileSettings.Free;
  except on E: Exception do begin
    ShowMessage('Fehler');
    FileSettings.Free;
  end;
  end;
end;
Mein Problem dabei ist dass ich nicht weiss ob man einfach so mehrere Try's schachteln kann. Habe irgendwo mal gelesen dass der Compiler für jeden Codeblock bei einem Try quasi einen "Ausweichcode" für den Fehlerfall anlegt, und das währen ja dann mehrere.

Die zweite Möglichkeit ist weit weniger elegant. Bitte klärt mich auf ^^

mkinzler 20. Jun 2006 18:12

Re: Frage zu mehreren Try's
 
Warum eigentlich 2 mal try eines würde doch reichen.

Delphi-Quellcode:
try
  ...
except
  on ...
finally
 ...
end;

Stefan Hueg 20. Jun 2006 18:13

Re: Frage zu mehreren Try's
 
Das funktioniert? Schande über mein Haupt....nu programmiere ich schon so lange mit Delphi und weiss das nicht....wieder was dazu gelernt...mal probieren ^^

SirThornberry 20. Jun 2006 18:16

Re: Frage zu mehreren Try's
 
die erste Variante ist völlig falsch denn du würdest filesettings auch mit Free versuchen frei zu geben wenn das Create schon fehlschlägt. Wenn das Create aber fehlschlägt ist nix frei zu geben. Und da die Variable lokal ist, ist sie auch nicht nil so das Free einen Fehler verursacht weil du es auf einen Speicherbereich anwendest wo gar kein Object liegt.

Stefan Hueg 20. Jun 2006 18:19

Re: Frage zu mehreren Try's
 
Der Quellcode:

Delphi-Quellcode:
try
  SettingFile := TIniFile.Create(ExtractFilePath(ParamStr(0))+ 'settings.ini');
except
  on E: Exception do
    ShowMessage('Fehler');
finally
  SettingFile.Free;
end;
funktioniert nicht. Mein Compiler muckt da rum.

@SirThornberry:
Also

Delphi-Quellcode:
try
  SettingFile := TIniFile.Create(ExtractFilePath(ParamStr(0))+ 'settings.ini');
finally
  SettingFile.Free;
end;
Sollte man nicht verwenden da nicht sichergestellt ist dass Create überhaupt erfolgreich war, habe ich das richtig verstanden?

SirThornberry 20. Jun 2006 18:28

Re: Frage zu mehreren Try's
 
genau, das Free soll ja nur ausgeführt werden wenn das Create erfolgreich war und somit auch speicher zum freigeben vorhanden ist.

DGL-luke 20. Jun 2006 18:32

Re: Frage zu mehreren Try's
 
Also ich stelle das create immer vor den ressourcenschutzblock.

Stefan Hueg 20. Jun 2006 19:04

Re: Frage zu mehreren Try's
 
Ok ich glaube ihr versteht noch nicht so recht was ich erreichen will ^^

Anderes Beispiel:
Delphi-Quellcode:
procedure TForm1.Button1Click(Sender: TObject);
var
  Test: TIniFile;
begin
  try
    Test := TIniFile.Create('C:\test.txt');
    Test.WriteString('Test', 'Test', 'Test');
    Test.Free;
  except
    on EIniFileException do
      ShowMessage('Fehler bei Ini-File');
  else
    ShowMessage('Irgend ein anderer Fehler');
  end;
end;
Wenn das Objekt erstellt, in die Ini-Datei geschrieben werden konnte: Kein Problem
Aber tritt bei WriteString beispielsweise ein Fehler auf, weil die Datei schreibgeschützt ist beispielsweise, wird das Objekt gar nicht mehr freigegeben, obwohl es erfolgreich erstellt wurde.

Ich müsste nun irgendwie herausfinden ob das Objekt erfolgreich erstellt wurde, dann kann ich sicher sagen dass ich es auch freigeben kann.

Khabarakh 20. Jun 2006 19:05

Re: Frage zu mehreren Try's
 
Ein Post über deinem steht die Lösung.

DGL-luke 20. Jun 2006 19:11

Re: Frage zu mehreren Try's
 
*sich von Khabarakh bestätigt sieht*

Ein Ressourcenschutzblock sieht (bei mir) so aus:

Delphi-Quellcode:
objekt := TObjekt.Create;
try
  objekt.dosomething;
  objekt.accessfragilethings;
finally
  objekt.Free;
end;
;)

(für ein zusätzliches except muss man tatsächlich schachteln! Zumindest bei D2005PE)

SirThornberry 20. Jun 2006 19:25

Re: Frage zu mehreren Try's
 
es muss auch nicht immer finally sein. folgendes geht auch:
Delphi-Quellcode:
try
  objekt := TObjekt.Create;
  try
    objekt.dosomething;
    objekt.accessfragilethings;
  except
    ShowMessage('Fehler beim arbeiten mit dem Object');
  end;
  objekt.Free;
except
  ShowMessage('Fehler beim erstellen des Objectes');
end;
Eben aus diesem Grund ist mir bis heute unbekannt wozu "finally" im zusammenhang mit "try" überhaupt existiert.

Stefan Hueg 20. Jun 2006 19:32

Re: Frage zu mehreren Try's
 
Zitat:

Zitat von DGL-luke
*sich von Khabarakh bestätigt sieht*

Ein Ressourcenschutzblock sieht (bei mir) so aus:

Delphi-Quellcode:
objekt := TObjekt.Create;
try
  objekt.dosomething;
  objekt.accessfragilethings;
finally
  objekt.Free;
end;
;)

(für ein zusätzliches except muss man tatsächlich schachteln! Zumindest bei D2005PE)

Das geht grundsätzlich, nur ist damit nicht sichergestellt ob das Objekt vorher überhaupt instanziert wurde, kann also zum Fehler führen ;)

Hawkeye219 20. Jun 2006 19:38

Re: Frage zu mehreren Try's
 
Dann mache es doch so:
Delphi-Quellcode:
try
  objekt := TObjekt.Create;
  try
    objekt.dosomething;
    objekt.accessfragilethings;
  finally
    objekt.Free;
  end;
except
  ShowMessage ('Fehler');
end;
Damit ist sichergestellt, daß objekt freigegeben wird, falls es erzeugt werden konnte.

Gruß Hawkeye

inherited 20. Jun 2006 20:29

Re: Frage zu mehreren Try's
 
^Shmia würde euch für diese art von aufruf von try...except lynchen... siehe sein TUTORIAL

Khabarakh 20. Jun 2006 20:37

Re: Frage zu mehreren Try's
 
@SirThornberry: Naja, es kommt sehr selten vor, dass man eine Exception in der Methode, die sie wirft, auch wieder auffängt. Also hat try-finally schon seine Berechtigung.

@Stefan Hueg: Nope, DGL-Lukes Methode ist dicht wie Wasser ... äh :stupid: ... wasserdicht. Wird eine Exception im Konstruktor ausgelöst, wird der Schutzblock gar nicht mehr ausgeführt.

Stefan Hueg 20. Jun 2006 21:03

Re: Frage zu mehreren Try's
 
Zitat:

Zitat von inherited
^Shmia würde euch für diese art von aufruf von try...except lynchen... siehe sein TUTORIAL

und @Khabarakh:

Habe mir sein Tutorial mal durchgelesen, dort wird der Konstruktor nicht in den Resourcenschutzblock aufgenommen.
In meinem genannten Programm kann ja, rein theoretisch, der Konstruktor von TIniFile ja zum Fehler führen (aus welchen Gründen auch immer).

Daher möchte ich ihn gerne in einen separaten Schutzblock aufnehmen. Das Beispiel

Delphi-Quellcode:
try
  objekt := TObjekt.Create;
  try
    objekt.dosomething;
    objekt.accessfragilethings;
  finally
    objekt.Free;
  end;
except
  ShowMessage ('Fehler');
end;
erscheint mir dabei sinnvoll. Es wird sowohl der Konstruktor als auch der Rest sicher geschützt. Elegant oder nicht, es ist meines Erachtens nach wasserdichter als wenn man den Konstruktor einfach nur Konstruktor sein lässt und seinem Schicksal überlässt.

Ich kann mich auch täuschen, aber ich versuche nur (bitte dafür nich hauen) das Programm so wasserdicht wie möglich zu machen. Dabei ist es die Frage, was man nicht explizit schützen muss, und beim Konstruktor bin ich mir eben unsicher.

Khabarakh 20. Jun 2006 21:13

Re: Frage zu mehreren Try's
 
Wie schon gesagt, DGL-Lukes Methode ist wirklich wasserdicht. Du verwechselst/vermischst da zwei Sachen, ein try-except-Block ist kein Ressourcenschutzblock.
Der Block in deinem Beispiel schützt nichts, außer vielleicht den Benutzer vor dem Standard-Exception-Dialog :stupid: .

Stefan Hueg 20. Jun 2006 21:15

Re: Frage zu mehreren Try's
 
Irgendwie will das nicht in meinen Kopf...Schlägt der Konstruktor fehl kann man das Objekt nicht freigeben da es erst gar nicht instanziert wurde -> Fehler entsteht der nicht behandelt wird?

DGL-luke 20. Jun 2006 21:53

Re: Frage zu mehreren Try's
 
Nein... löst der Konstruktor eine Exception aus, wird die Prozedur abgebrochen -> das "try" wird gar nicht angeschnitten -> das finally auch nicht -> es wird nicht versucht, etwas freizugeben. Die Exception bubbelt sich dann ihren Weg hinauf, eventuell bis zur messagebox.

Und nochwas: Wenns schon im Konstruktor knallt, kann mans eh vergessen ;)


Alle Zeitangaben in WEZ +1. Es ist jetzt 21:41 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 by Thomas Breitkreuz