![]() |
Re: Frage zu Try..Finally/Except
Delphi-Quellcode:
ist doch völlig ok
type
TMyClass = class public constructor Create; destructor Destroy;override; end; constructor TMyClass.Create; begin inherited Create; raise Exception.Create('exception within a constructor'); end; destructor TMyClass.Destroy; begin raise Exception.Create('exception within a destructor'); inherited; end; procedure TForm1.Button1Click(Sender: TObject); var myVar: TMyClass; begin myVar:= TMyClass($badf00d); //stack contains rubbish try myVar:= TMyClass.Create; try finally myVar.Free; end; except on E:Exception do outputDebugString(PChar('Exception:'+E.Message)); end; end; hier rufts du alles auch richtig auf der destructor wird ja auch nur aufgerufen weil myVar.free auch durchgeführt wird es entsteht keine Exception
Delphi-Quellcode:
wird NUR aufgerufen wenn das Objeckt nicht erzeugt werden konnteexcept on E:Exception do outputDebugString(PChar('Exception:'+E.Message)); end; und das Objekt wird erzeugt der erste Wert für myChar wird ja auch überschrieben, deshalb ist alles ok mfg Tyrael |
Re: Frage zu Try..Finally/Except
Das Objekt wird nicht erzeugt, weil innerhalb des Konstruktors eine Exception geworfen wird und der vom Delphi-Compiler implizit generierte Code das Exemplar wieder freigibt (nachprüfbar im CPU-Fenster, mit einem geeigneten Profiler oder mithilfe von GetHeapStatus.TotalAllocated).
Bitte vergewissere Dich, dass der Destruktor implizit aufgerufen wird, indem Du die Zeile myVar.Free auskommentierst:
Delphi-Quellcode:
Und dann sieh Dir die Ausgabe von OutputDebugstring an. Notfalls solltest Du weitere Aufrufe dieser Prozedur in den Konstruktor/Destruktor einfügen, um den Programmverlauf nachzuverfolgen.
myVar:= TMyClass.Create;
try finally // myVar.Free; end; Noch einmal: Der Except-Abschnitt fängt nicht die Exception des Konstruktors ab, diese wird durch die Exception des Destruktors "verschluckt". Deshalb und auch, weil die Ressourcen im trivialen Fall ohnehin freigegeben werden, verstehe ich nicht, warum Du den Except-Block benötigst? Welchen Vorteil hat man hierdurch? |
Re: Frage zu Try..Finally/Except
Zitat:
Delphi-Quellcode:
wegen der nicht-vorinitialisierten Werte auf dem Stack zu problemen führen kann (siehe Kommentare).
myVar:= TMyClass($badf00d); //stack contains rubbish
try //myVar won't be altered since Create raises an exception myVar:= TMyClass.Create; finally //eq to TMyClass($badf00d).Free ->AccessViolation myVar.Free; end; |
Re: Frage zu Try..Finally/Except
Ja du hast vollkommen Recht, wenn beim kreieren des Objektes eine Ausnahme auftritt
und das Objekt nicht erstellt werden konnte, wird der Destructor aufgerufen(mini "garbage collector"). Du bräuchtest dich prinzipiell darum nicht mehr zu kümmern, aber... ...direkt nach dem Destructor Aufruf wird der Except Block aufgerufen.... ...es wird also eine Ausnahme erzeugt... ...in diesem könntest du jetzt auf das schiefgegangene Kreieren reagieren und je nach dem vielleicht einen DebugLogger einsetzten oder irgend ne andere Prozedur/Funktion aufrufen in der du alles wieder glattbügelst... ..oder einfach nix im Äußeren except Block schreibst... ..dann wird keine Ausnahme geworfen und du hast keine "lästige" Exception Anzeige... Wie gesagt es geht auch ohne das Äußere try except , aber wenn du 100%-ige Version haben möchtest kann ich das try except drumherum nur empfehlen. Hilft ungemein bei grossen Projekten, wenn du Fehler suchst, weil dann kannst du dir u.U. die suche sparen, z.B. wenn du einen DebugLog mitlaufen läßt. Ich würde mir angewöhnen diesen Äußeren try except Block IMMER zu schreiben. Ich habs mir angewöhnt, und es hilft wirklcih bei der Fehlersuche. mfg Tyrael |
Re: Frage zu Try..Finally/Except
Zitat:
Sicherlich, das ist eine funktionierende Lösung. Ich persönlich empfinde Exceptions weder als lästig noch als überflüssig. Stattdessen sind sie oft sinnvolle Helfer für außergewöhliche Situationen. Jedoch kann und sollte nicht jede Zeile Code mit jeder Ausnahmebedingung umgehen, deshalb "übersetze" ich Exceptions lieber und reiche sie bis zu jemanden durch (ExceptionChaining, ExceptionWrapping), der sie schließlich sinnvoll verarbeitet (zB der zuständige Broker des Frameworks oder der zuständige Kontext). Hier kann zur detaillierten Beschreibung durch die kumulierte Information genaue Ursache und Position der ersten Exception (hier: Konstruktur der Klasse TMyClass) über die jeweiligen Ebenen des Aufrufs (sollte aus Foo erzeugt werden, die von Bar aufgerufen wurde, in Thread FooBar (es leben benannte Threads!)). Für diese und ähnliche Aufgaben gibt es für Delphi gute Lösungen! Interessant ist vielleicht der Link aus ![]() |
Re: Frage zu Try..Finally/Except
danke luckie ^^ und danke an die anderen, beim grossen talk :-D
|
Alle Zeitangaben in WEZ +1. Es ist jetzt 08:45 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