Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Object-Pascal / Delphi-Language (https://www.delphipraxis.net/32-object-pascal-delphi-language/)
-   -   Delphi Try-Finally und Try-Except zusammen nutzen? (https://www.delphipraxis.net/154794-try-finally-und-try-except-zusammen-nutzen.html)

OrNEC 25. Sep 2010 14:54

Delphi-Version: 7

Try-Finally und Try-Except zusammen nutzen?
 
Hallo, hab da eine Frage wo ich nicht weiter komme.
Ich schreibe wie folgt eine Datei:

Delphi-Quellcode:
procedure TForm1.FormClose(Sender: TObject);
var
  Ini: TIniFile;
begin
  Ini:=TIniFile.Create('C:\Test.ini');
  try
    {hier schreiben}
  finally
    Ini.Free;
  end;
end;
Was ist allerdings wenn sich mein Programm auf einer CD befindet wo es keine Schreibrechte gibt? Da, hab ich gelesen, ist besser Try-Except zu verwenden, aber wenn ich Finally durch Except ersetze wie gebe die Ini frei?

Danke!

Uwe Raabe 25. Sep 2010 14:56

AW: Try-Finally und Try-Except zusammen nutzen?
 
Delphi-Quellcode:
Ini := TIniFile.Create('C:\Test.ini');
try
  try
    {hier schreiben}
  except
    { hier die Exception aber auch behandeln! Bei Bedarf über raise weiterreichen. }
  end;
finally
  Ini.Free;
end;

OrNEC 25. Sep 2010 15:01

AW: Try-Finally und Try-Except zusammen nutzen?
 
Danke :thumb:

Ich dachte auch so ähnlich, war mir aber nicht sicher, ob das so gemacht wird, wollte nen Profi fragen. Also danke noch ma!

xZise 25. Sep 2010 15:08

AW: Try-Finally und Try-Except zusammen nutzen?
 
Das ist der gängige Weg mit Delphi. In anderen Programmiersprachen hast du netterweise auch ein try-except-finally Konstrukt.

Zum Beispiel in Java:
Code:
try {

} catch (Exception e) {

} finally {

}
MfG
Fabian

himitsu 25. Sep 2010 15:13

AW: Try-Finally und Try-Except zusammen nutzen?
 
Zitat:

Zitat von xZise (Beitrag 1051859)
Zum Beispiel in Java:
Code:
try {

} catch (Exception e) {

} finally {

}

Intern ist Try-Finally und Try-Except fast das Selbe, jedenfalls wird mit den selben Struckturen gearbeitet.

Das Problem ist aber, wenn in einem der Except/Finally-Blöcke eine Exception auftritt.
Darum braucht man eben 2 verschachtelte Schutzblöcke, Delphi baut sich sowas leider nicht selber zusammen. :cry:

sowas hätte mir auch gefallen
Delphi-Quellcode:
try

except

finally

end;
@xZise: Was passiert denn, wenn in Catch eine Exception auftritt?
Wird dann Finally noch ausgeführt?[/QUOTE]


Wierum man es letztendlich verschachtelt, hängt von der Aufgabe ab.
Delphi-Quellcode:
Ini := TIniFile.Create('C:\Test.ini');
try
  try
    ...
  except
    ...
  end;
finally
  Ini.Free;
end;
TIniFile greift im Constructor nicht auf die Datei zu, weswegen es hier geht.
TMemIniFile macht dieses aber, weshalb man es hier eventuell andersrum machen sollte, falls z.B. schon beim Öffnen/Auslesen ein Fehler auftritt.
Delphi-Quellcode:
try
  Ini := TMemIniFile.Create('C:\Test.ini');
  try
    ...
  finally
    Ini.Free;
  end;
except
  ...
end;

himitsu 25. Sep 2010 15:16

AW: Try-Finally und Try-Except zusammen nutzen?
 
[edit] *verklickt*

xZise 25. Sep 2010 15:54

AW: Try-Finally und Try-Except zusammen nutzen?
 
Moin himitsu,
Zitat:

Zitat von himitsu (Beitrag 1051862)
[...]sowas hätte mir auch gefallen[...]

Joar manchmal ganz nett. Und da könnte die Compiler magic auch das in das "alte" Format umwandeln.


Zitat:

Zitat von himitsu (Beitrag 1051862)
Delphi-Quellcode:
try

except

finally

end;
@xZise: Was passiert denn, wenn in Catch eine Exception auftritt?

Beurteile es selber:
Code:
C:\Users\xZise\Desktop\löschen>"C:\Program Files\Java\jdk1.6.0_21\bin\javac.exe"
 Main.java

C:\Users\xZise\Desktop\löschen>java Main
Throw an exception.
Exception caught. Throw another exception!
Now I'm in the finally block.
Exception in thread "main" java.lang.ArithmeticException: / by zero
        at Main.main(Main.java:10)
Code:
public class Main {

    public static void main(String[] a) {
   
        try {
            System.out.println("Throw an exception.");
            int i = 2 / 0;
        } catch (Exception e) {
            System.out.println("Exception caught. Throw another exception!");
            int j = 2 / 0;
        } finally {
            System.out.println("Now I'm in the finally block.");
        }
        System.out.println("Good bye.");
    }

}
MfG
Fabian

sx2008 25. Sep 2010 16:14

AW: Try-Finally und Try-Except zusammen nutzen?
 
Wenn man try..finally und try..except gemeinsam benötigt sollte man mal
über Unterfunktionen nachdenken.

In folgendem Beispiel werden Try..finally und try..except in verschiedenen
Methoden verwendet.
Der Code gewinnt dadurch an Klarheit und wird offener für zukünftige Veränderungen.
Delphi-Quellcode:
procedure TForm1.LoadIniFile(const filename:String);
var
  Ini : TIniFile;
begin
  Ini := TIniFile.Create(filename);
  try
  ...
  finally
    Ini.Free;
  end;
end;

procedure TForm1.LadeKonfig;
begin
  try
    LoadIniFile('myconfig.ini');
  except
    on E:Exception do
    begin
      E.Message := 'Konfiguration konnte nicht geladen werden'#13#10+
        E.Message;
      raise;
    end;
  end;
end;

himitsu 25. Sep 2010 16:17

AW: Try-Finally und Try-Except zusammen nutzen?
 
Schön, dann scheint es in Java wenigstens richtig behandelt zu werden. :-D


Aber sowas wie
Delphi-Quellcode:
int j = 2 / 0;
würde Delphi garnicht erst kompilieren :stupid:

rollstuhlfahrer 25. Sep 2010 17:01

AW: Try-Finally und Try-Except zusammen nutzen?
 
nun ja, Delphi macht da einiges mit:
Delphi-Quellcode:
procedure TForm1.Button1Click(Sender: TObject);
var
  i: Extended;
  j, k: Integer;
begin
// 1
ShowMessage(Format('%1.4f', [(5/0)]));

// 2
ShowMessage(FloatToStr(5/0));

// 3
i := 5/0;
ShowMessage(FloatToStr(i));

// 4
j := Trunc(5/0);
ShowMessage(IntToStr(j));

// 5
k := 5 div 0;
ShowMessage(IntToStr(k));
end;
Mit den beiden Zeilen, die mit 1, 2 und 3 beschriftet sind, hat Delphi absolut keine Probleme. Bei Zeile mit 4 meckert es mit "Konstantenausdruck verletzt untere Grenze" und erst bei der Zeile mit 5 bemerkt es, dass das jetzt schon wieder eine Division durch 0 ist und zeigt einen entsprechenden Fehler an.

Bernhard

himitsu 25. Sep 2010 18:25

AW: Try-Finally und Try-Except zusammen nutzen?
 
Ich nutz ja recht selten etwas ala "div by null",
aber als ich mich das letzte mal verschrieben hatte, da war's glaub ich auch das div (div 0 statt div 10 geschrieben).
Mir ist aber so, als wenn ich sowas auch mal mit einem / hatte :gruebel:

xZise 26. Sep 2010 16:03

AW: Try-Finally und Try-Except zusammen nutzen?
 
Soweit ich weiß, kann man eine Gleitkommazahl durch 0 teilen (das Ergebnis ist dann NaN).

Und naja, Java meckert ziemlich viel rum:
  • Code:
    int answer() {}
    Code:
    int answer() {
        if (Math.random() < 0.5) { return 0; }
    }
    missing return statement
  • Code:
    int answer() throws Exception { 
       throw new Exception();
       return 42;
    }
    unreachable statement

MfG
Fabian

Benmik 29. Sep 2020 11:23

AW: Try-Finally und Try-Except zusammen nutzen?
 
Hat sich hier eigentlich in den letzten 10 Jahren etwas getan? Ist in den nächsten 100 Jahren etwas zu erwarten?

Ich habe laufend Routinen, in denen sowohl Fehler abgefangen als auch Ressourcen freigegeben werden müssen. Dieses
Delphi-Quellcode:
Try
  Try
finde ich furchtbar, und man sieht es auch selten. Es soll auch einen Haufen Code erzeugen.
Was ist eigentlich damit, dürfte ein Profi sich sowas leisten, oder wäre sein Ruf dann dahin?
Delphi-Quellcode:
  Except
    Liste.Free;
    Stream.Free;
    Objekt.Free;
    Showmessage('Mist!');
    exit(False);
  end;
  Liste.Free;
  Stream.Free;
  Objekt.Free;
end;
Wenn es noch gestattet ist und nicht als OT angesehen wird, würde ich auch gern auf diesen Beitrag bei SO verweisen (selbstverständlich führt auch dort David Heffernan seine Klinge). Ich habe nämlich auch angefangen, sehr viele Prozeduren in Funktionen umzuwandeln, in denen der Wert über einen var-Parameter zurückgegeben wird und Result mitteilt, ob alles geklappt hat.
Delphi-Quellcode:
If BestimmeWert(var Wert:string) then ...
gefällt mir codetechnisch viel besser als
Delphi-Quellcode:
Wert := BestimmeWert;
If Wert <> '' then ...
.

haentschman 29. Sep 2020 11:35

AW: Try-Finally und Try-Except zusammen nutzen?
 
Hallöle...:P
Zitat:

Exit veranlasst die aufrufende Prozedur, mit der Anweisung nach dem Punkt fortzufahren, an dem die Prozedur aufgerufen wurde
http://docwiki.embarcadero.com/Libra...de/System.Exit
try/finally bewirkt das der Finally Block immer ausgeführt wird. Damit brauchst du die Freigaben nicht doppelt schreiben.
https://de.wikipedia.org/wiki/Don%E2...epeat_yourself

Benmik 29. Sep 2020 11:37

AW: Try-Finally und Try-Except zusammen nutzen?
 
Nein, schau doch noch mal hin ...
(zum Verständnis: haentschmanns Antwort ist nun nicht mehr, was sie mal war...)

haentschman 29. Sep 2020 11:43

AW: Try-Finally und Try-Except zusammen nutzen?
 
Zitat:

zum Verständnis: haentschmanns Antwort ist nun nicht mehr, was sie mal war
...wer kann denn schon ahnen, daß die Antwort gleich gelesen wird. :stupid: Ich hatte die ersten Freigaben übersehen und mich auf das EXIT konzentriert.:wink:

Benmik 29. Sep 2020 11:57

AW: Try-Finally und Try-Except zusammen nutzen?
 
Zitat:

Zitat von haentschman (Beitrag 1474511)
try/finally bewirkt das der Finally Block immer ausgeführt wird. Damit brauchst du die Freigaben nicht doppelt schreiben.

Na klar, die Freigabe klappt dann, aber die Exceptionbehandlung nicht mehr, das ist ja der Grund für das doppelte Try.

Aber jetzt anders, wie macht ihr das?
1. Doppeltes Try
2. Doppeltes Try umgehen
3. Zweite Variante doch wohl nicht, aber nur gefühlsmäßig, oder aus sachlichem Grund?

Delphi.Narium 29. Sep 2020 12:35

AW: Try-Finally und Try-Except zusammen nutzen?
 
Bevorzugt doppeltes Try.

Wenn möglich in Funktionen ausgelagert, die mir sagen, ob's erfolgreich war bzw. einen definierten Wert zurückgeben, mit dem ich garantiert weiter arbeiten kann.

Also ähnlich zu Deinem Beispiel mit Funktion und Var-Parametern.

Var-Parameter immer dann, wenn die Funktion mehr als einen Wert liefern muss oder im Fehlerfalle anders vorgegangen werden muss, als im Erfolgsfalle.

Also sowas:
Delphi-Quellcode:
if MeineFunktion(1..n Parameter) then begin
  // Weiterverarbeitung im Erfolgsfall.
end else begin
  // Weiterverarbeitung im Fehlerfall.
end;
// oder eben, Fehler in der Funktion werden vollständig behandelt und Rückgabewert ist für die Weiterverarbeitung geeignet.
Variabel := MeineFunktion(1..n Parameter);
In beiden Fällen gilt: Als Var-Parameter nur die, die auch verändert werden müssen, die übrigen als Const-Parameter.
Delphi-Quellcode:
function MeineFunktion(0..n Const-Parameter, 1..n Var-Parameter) : Boolean;
function MeineFunktion(1..n Const-Parameter) : BedarfsgerechterTyp;
Funtionen können als Rückgabewert ggfls. aber auch mal vom Typ "Record of wasauchimmer" sein, dann hat man zwar nur einen Rückgabewert, der kann aber als Record mehrere Werte enthalten ;-) (ist aber eher die Ausnahme, meist nur dann, wenn aus der Funktion irgendwas aufgerufen wird, was sowieso schon 'nen Record liefert.)

Benmik 29. Sep 2020 12:54

AW: Try-Finally und Try-Except zusammen nutzen?
 
Das wäre alles auch nach meinem Gusto (vielleicht ein bisschen außer dem doppelten Try). Angenehm zu wissen.

Aviator 29. Sep 2020 19:04

AW: Try-Finally und Try-Except zusammen nutzen?
 
Ich mache das auch mit einem doppelten
Delphi-Quellcode:
try
. Nur bin ich mir nie so sicher, wie die Reihenfolge am sinnvollsten ist.

So:
Delphi-Quellcode:
try
  obj := TObject.Create;
  try
    // Some code
  except
    // Exception handling
  end;
finally
  obj.Free;
end;
Oder doch so:
Delphi-Quellcode:
try
  obj := TObject.Create;
  try
    // Some code
  finally
    obj.Free;
  end;
except
  // Exception handling
end;
Ich würde ja fast sagen, dass die letztere Variante die sinnvollere sein müsste. Weil prinzipiell könnte es ja schon im Constructor des zu erzeugenden Objektes knallen. In der ersten Variante würde das dann nicht abgefangen werden.

Wie seht ihr das?

PS: Ich würde mir auch ein
Delphi-Quellcode:
try .. except .. finally
Konstrukt wie in C# wünschen.

himitsu 29. Sep 2020 20:40

AW: Try-Finally und Try-Except zusammen nutzen?
 
Welche Reihenfolge, das kommt drauf an, ob
erst Freigeben und dann Fehlerbehandlung, welche auch das Freigeben mit behandlet,
oder erst die Fehlerbehandlung und dann die Freigabe.

Eventuelle Speicherprobleme zuerst freigeben und dann behandlen,
aber muß man beim Behandelt auf das zugreifen, was knallte, dann Freigeben zuletzt.

Auch Sperren (CriticalSections und Datei- oder Datenbankzugriffe) meist zuerst beenden und dann z.B. den Fehlerdialog anzeigen,
weil andersrum kann es sonst schnell einen Deadlock geben.

Zitat:

Delphi-Quellcode:
try
  obj := TObject.Create;
  try
    // Some code
  except
    // Exception handling
  end;
finally
  obj.Free;
end;

Nein!

Lies dir die Compiler-Warnung durch und du weißt warum.

Delphi-Quellcode:
obj := TObject.Create;
try
  try
    // Some code
  except
    // Exception handling
  end;
finally
  obj.Free;
end;

Aviator 30. Sep 2020 07:14

AW: Try-Finally und Try-Except zusammen nutzen?
 
Zitat:

Zitat von himitsu (Beitrag 1474545)
Zitat:

Delphi-Quellcode:
try
  obj := TObject.Create;
  try
    // Some code
  except
    // Exception handling
  end;
finally
  obj.Free;
end;

Nein!

Lies dir die Compiler-Warnung durch und du weißt warum.

Das war leider nur ein Fehler bei der Eingabe, da ich das schnell hier im Editor gemacht habe. Dass das Create oben drüber gehört ist mir klar. Dafür brauche ich auch keine Compiler Warnung.

Frickler 30. Sep 2020 12:36

AW: Try-Finally und Try-Except zusammen nutzen?
 
Zitat:

Zitat von himitsu (Beitrag 1474545)
Delphi-Quellcode:
obj := TObject.Create;
try
  try
    // Some code
  except
    // Exception handling
  end;
finally
  obj.Free;
end;

Alternativ:

Delphi-Quellcode:
obj := nil;
try
  obj := TObject.Create;
  try
    // Some code
  except
    // Exception handling
  end;
finally
  obj.Free;
end;
Die Alternativversion ist vor allem sinnvoll, wenns mehrere Objekte sind und man nicht ein try..finally pro Objekt habe will:

Delphi-Quellcode:
obj1 := nil;
obj2 := nil;
obj3 := nil;
try
  obj1 := TObject.Create;
  obj2 := TObject.Create;
  obj3 := TObject.Create;
  try
    // Some code
  except
    // Exception handling
  end;
finally
  obj1.Free;
  obj2.Free;
  obj3.Free;
end;
statt

Delphi-Quellcode:
obj1 := TObject.Create;
try
  obj2 := TObject.Create;
  try
    obj3 := TObject.Create;
    try
      try
        // Some code
      except
        // Exception handling
      end;
    finally
      obj3.Free;
    end;
  finally
    obj2.Free;
  end;
finally
  obj1.Free;
end;

himitsu 30. Sep 2020 13:43

AW: Try-Finally und Try-Except zusammen nutzen?
 
Zitat:

Delphi-Quellcode:
finally
  obj1.Free;
  obj2.Free;
  obj3.Free;
end;

Sowas aber auch nur, wenn man im Normallfall sicherstellen kann, dass es beim Freigeben nicht knallt.


Alle Zeitangaben in WEZ +1. Es ist jetzt 03:06 Uhr.

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz