![]() |
AW: Wieso Speicheranforderung in Try...Finally ?
@FredFesl
So selbstbewußt hätte ich es nicht vortragen können, sehe das aber genau so. Ansonsten müsste man (wenn man es genau machen wollte) beim Erzeugen von 10 Objekten nacheinander auch 10 verschachtelte Schutzblöcke erzeugen (für jedes Objekt einen). Es kann ja jeder machen wie er will, aber der Sinn erschließt sich mir (in den meisten Fällen) nicht. @WM_CLOSE+Luckie Wenn ein Programm mit einem solch gravierenden Fehler wochenlang durchläuft, ist mit dem Ergebnis wohl ohnehin nix anzufangen. Das gilt jedenfalls, wenn der Fehler nicht komplett bereigit wird (incl. aller Daten und Zustände). Und diese Bereinigung kann man eigentlich nur gewährleisten, wenn man mit einem bestimmten Fehler rechnet, den man aber nicht unbedingt vermeiden kann (E/A-Funktionen). |
AW: Wieso Speicheranforderung in Try...Finally ?
Ich sage es mal so "schau dir meinen FileSplitter (hier in der DP) mal an.
weiter siehe *1 Ja, wenn nach einem Knall (Exception) sowieso alles zu spät ist, könnte man es auch gleich sein lassen ... Windows räumt ja auf. Aber dennoch sollte man es in einem gewissen Maße machen, denn wenn man etwas immer gleich macht, egal ob das Programm wichtig oder nutzlos ist, dann hat man a) ähnliche Programmstrukturen (Wiederverwendbarkeit) und damit auch ein leichteres Arbeiten, da man sich nur an eine Struktur halten muß, was auch das Lesen/Verstehen vereinfacht und wenn man dann durch das viele Programmieren dieses total verinnerlicht hat, dann kann man es an wichtigen stellen nicht so schnell vergessen. *1 Ja, auch ich schreibe schonmal Programme ganz ohne Try-Finally, denn unter gewissen Umständen ist sowas garnicht nötig, da z.B. die WinAPI an vielen Stellen mit Fehlercodes arbeitet und nicht mit Exceptions. Wenn es dort Probleme gibt, dann werden diese nicht gleich mit einer Exception quitiert und man kann/muß diese Fehler dann anderes behanden. (knallt es dort wirklich mal mit einer Exception durch, dann ist sowieso alles zu spät und jede weitere Bemühung eher umsonst) Mit genügend Wissen/Erfahrung kennt man gewisse Schwachstellen oder auch Ecken, wo eigentlich nie was schief laufen kann ... in soeinem Kall kann man die Fehlerbehandlung auch schonmal etwas "anpassen". Aber im Normalfall sollte man einfach alles Schützen, wenn man weiß ja nie was mal passiert ... ganz besonders bei Codes, welche man anderen zur Verfügung stellt. siehe ![]() Das Original hieß
Delphi-Quellcode:
Was eigentlich auch schon sicher genug ist. (siehe meine Erklärung dort drüben)
Result := '';
Parse := TStringList.Create; Row := TStringList.Create; try Parse.Text := GetBarcodesResult; Aber dennoch, ein gewisser (ausreichender) Schutz wird dennoch verbaut, auch wenn einige meinen könnten "wozu ... ist doch eh umsonst?". Denn weißt du, ob der Code nicht mal in einem wichtigen Programm verbaut würde? |
AW: Wieso Speicheranforderung in Try...Finally ?
Zitat:
Aber du suchst ja nach einer Erklärung warum "immer" try-finally verwenden sollte. 1. Grund. Warum denn nicht? Ein vergessenes try-finally kann ein Fehler sein, aber ein try-finally, dass nicht notwendig ist, ist niemals falsch. vielmehr macht es meinen Code robuster (z.B. für Erweiterungen oder für Verwendung an anderer Stelle). Meine Erfahrung: Da wo man das try-finally weglassen könnte, da stört es nicht und da wo es stört, kann man es nicht weglassen. 2. Grund: Lesbarkeit Finde ich im Code eine Stelle an der eine Resource belegt oder ein Objekt erzeugt wird, will ich sofort als nächstes wissen wo die Freigabe ist. Ein try-finally ist da eine schöne Klammer die mich zu der Stelle mit der Freigabe führt. 3. Grund: Leichtes überprüfen auf Korrektheit Um sagen zu können, dass Code in der Form
Code:
kein Speicherleck produziert, muss ich für alle Zeilen dazwischen garantieren, dass diese keine Exceptionen werfen. Sobald da eine Prozedure aufgerufen wird, ist das keineswegs trivial.
MyStringList := TStringlist.Create;
<Zeile1> <zeile2> <Zeile3> MyStringList.Free; Zeig doch mal eine Code-Stelle aus einem deiner Programmen wo dich so ein try-finally so richtig nervt. |
AW: Wieso Speicheranforderung in Try...Finally ?
Zitat:
Bei mir ist es eigentlich eher umgekehrt. Wenn in meinen Quelltext mal ein Schutzblock fehlt, dann ist das bei einer späteren Inspektion des Quelltextes immer ein Punkt, bei dem ich dann u.U. länger nachdenke, ob das an dieser Stelle tatsächlich legitim ist. D.h. ich verwende eventuell mehr Zeit bei der Wartung eines Quelltextes, wenn der Schutzblock fehlt, als wenn ich ihn konsequent einbaue. D.h. der Schutzbock um "b.work" in dem Eingangs genannten Beispiel ist schon deshalb sinnvoll, weil ich bei der Wartung nicht in b.work reingehen muss um zu prüfen, ob da auch wirklich keine Exception auftreten kann. Impliziert das Wort "Schutzblock" nicht schon, dass es sich um einen Security-Layer handelt? Und nein, ich kann mir keinen anderen sinnvollen Einsatz von Try-finally-Blöcken vorstellen, als genau diesen. Letztendlich ist es also die Frage, will ich auf Nummer sicher gehen, oder glaube ich, dass ich und alle anderen Verkehrsteilnehmer so gut sind, das niemals ein Unfall passieren kann (bzw. die Konsequenzen eines Unfalls sind mir einfach egal). Das muss jeder für sich entscheiden. |
AW: Wieso Speicheranforderung in Try...Finally ?
Zitat:
Wenn "mein Leben" das Programm ist, dann benötige ich den Sicherheitsgurt, denn das Fahren ist nur eine Aktion, die kontrolliert schiefgehen können muss. Ist "die Fahrt" mein Programm, dann muss ich mich nicht anschnallen. Peng => Programm-Neustart. Wieso muss ich einen Sicherheitsgurt tragen, wenn ich bei einem Unfall sowieso von Vorne anfange? Zitat:
Zitat:
Anderes Beispiel: Grundsätzlich eine Variable initialisieren: Stört nicht, wird eh wegoptimiert und ist robust. Und überflüssig und blöd. Zitat:
Zitat:
Delphi-Quellcode:
f := TFoo.Create;
Try b := TBar.Create Try b.DoSomething(); f.Work(); Finally b.Free End Finally f.free; End; // --- vs f := TFoo.Create; b := TBar.Create b.DoSomething(); f.Work(); b.Free f.free; |
AW: Wieso Speicheranforderung in Try...Finally ?
Zitat:
So, wie wenn wir immer erzählen, das man die Ampel nur bei 'grün' überqueren darf, aber: -unter uns-, wenn sonst keiner da ist, WTF. |
AW: Wieso Speicheranforderung in Try...Finally ?
Prima, jetzt werden wir konkret :thumb:
Zitat:
Delphi-Quellcode:
und wenn ich diesen Code sehe ...
b := TBar.Create;
try b.DoSomething(); finally b.Free end f := TFoo.Create; try f.Work(); finally f.free; end;
Delphi-Quellcode:
sehe ich 2 potenzielle Speicherlöcher. Um sicher zu gehen, dass der Code keine Speicherlöcher erzeugt, muss ich nun prüfen, ob TBar.Create, b.DoSomething und f.Work keine Exceptions werfen. Falls ich Glück habe und TBar.Create erstellt, wie ich anhand der Namen vermute, tatsächlich ein neues Objekt, bin ich allerdings schnell damit fertig, weil dann eine EOutOfMemory-Exception geworfen werden könnte und damit wäre der Code für mich definitiv gefährlich.
f := TFoo.Create;
b := TBar.Create b.DoSomething(); f.Work(); b.Free; f.free; |
AW: Wieso Speicheranforderung in Try...Finally ?
Ich hätte da auch noch etwas Senf dazu: Es mag ja durchaus sein, daß zum Zeitpunkt der Programmierung das Freigeben eines Objekts auch nach einer Exception ziemlich egal ist. Das muss aber nicht für immer so sein. Ist zwar etwas konstruiert, aber man stelle sich vor, daß das Objekt eine externe Resource belegt (z.B. eine Server-Verbindung aufbaut, einen COM-Server startet oder einen Lizenzzähler hochzählt), die unter allen Umständen wieder freigegeben werden muss.
Der Punkt dabei ist, daß dieses Verhalten vielleicht erst später eingebaut wird oder womöglich erst zur Laufzeit bestimmt wird. Dann möchte man ja auch nicht alle Instanzen in allen Programmen durchgehen, ob die denn auch schön brav in ein try-finally geklammert sind. Insofern ist ein try-finally Block etwas, daß mir womöglich meine zukünftige Arbeit erleichtert und mich vor meinen eigenen Fehlern schützt. |
AW: Wieso Speicheranforderung in Try...Finally ?
Wie sähe es denn so aus?
Delphi-Quellcode:
f := TFoo.Create;
b := TBar.Create b.DoSomething(); f.Work(b); b.DoOther; b.Free f.free; |
AW: Wieso Speicheranforderung in Try...Finally ?
Lös doch einmal eine Exception in einem der Objekte aus. Kommst Du dann noch bis zum Free?
|
Alle Zeitangaben in WEZ +1. Es ist jetzt 07:03 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