![]() |
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:
Beispiel 2:
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;
Delphi-Quellcode:
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.
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; Die zweite Möglichkeit ist weit weniger elegant. Bitte klärt mich auf ^^ |
Re: Frage zu mehreren Try's
Warum eigentlich 2 mal try eines würde doch reichen.
Delphi-Quellcode:
try
... except on ... finally ... end; |
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 ^^
|
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.
|
Re: Frage zu mehreren Try's
Der Quellcode:
Delphi-Quellcode:
funktioniert nicht. Mein Compiler muckt da rum.
try
SettingFile := TIniFile.Create(ExtractFilePath(ParamStr(0))+ 'settings.ini'); except on E: Exception do ShowMessage('Fehler'); finally SettingFile.Free; end; @SirThornberry: Also
Delphi-Quellcode:
Sollte man nicht verwenden da nicht sichergestellt ist dass Create überhaupt erfolgreich war, habe ich das richtig verstanden?
try
SettingFile := TIniFile.Create(ExtractFilePath(ParamStr(0))+ 'settings.ini'); finally SettingFile.Free; end; |
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.
|
Re: Frage zu mehreren Try's
Also ich stelle das create immer vor den ressourcenschutzblock.
|
Re: Frage zu mehreren Try's
Ok ich glaube ihr versteht noch nicht so recht was ich erreichen will ^^
Anderes Beispiel:
Delphi-Quellcode:
Wenn das Objekt erstellt, in die Ini-Datei geschrieben werden konnte: Kein Problem
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; 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. |
Re: Frage zu mehreren Try's
Ein Post über deinem steht die Lösung.
|
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) |
Re: Frage zu mehreren Try's
es muss auch nicht immer finally sein. folgendes geht auch:
Delphi-Quellcode:
Eben aus diesem Grund ist mir bis heute unbekannt wozu "finally" im zusammenhang mit "try" überhaupt existiert.
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; |
Re: Frage zu mehreren Try's
Zitat:
|
Re: Frage zu mehreren Try's
Dann mache es doch so:
Delphi-Quellcode:
Damit ist sichergestellt, daß objekt freigegeben wird, falls es erzeugt werden konnte.
try
objekt := TObjekt.Create; try objekt.dosomething; objekt.accessfragilethings; finally objekt.Free; end; except ShowMessage ('Fehler'); end; Gruß Hawkeye |
Re: Frage zu mehreren Try's
^Shmia würde euch für diese art von aufruf von try...except lynchen... siehe sein TUTORIAL
|
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. |
Re: Frage zu mehreren Try's
Zitat:
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:
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.
try
objekt := TObjekt.Create; try objekt.dosomething; objekt.accessfragilethings; finally objekt.Free; end; except ShowMessage ('Fehler'); end; 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. |
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: . |
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?
|
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