Delphi-PRAXiS
Seite 1 von 5  1 23     Letzte »    

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Algorithmen, Datenstrukturen und Klassendesign (https://www.delphipraxis.net/78-algorithmen-datenstrukturen-und-klassendesign/)
-   -   Wieso Speicheranforderung in Try...Finally ? (https://www.delphipraxis.net/162214-wieso-speicheranforderung-try-finally.html)

FredlFesl 12. Aug 2011 18:07

Wieso Speicheranforderung in Try...Finally ?
 
Hi Gemeinde,

Hier wird einem ständig empfohlen, Speicheranforderungen und -freigabe unbedingt immer in Try-Finally-Blöcke zu packen ("Resourcenschutzblöcke")

Ich verstehe den Sinn nur bedingt. Natürlich ist es manchmal sinnvoll, aber eigentlich nur, um einen Securitylayer um eine Methode zu legen, à la:
Delphi-Quellcode:
Procedure TMyClass.QuiteAbstractMethod;
Begin
  helper := THelper.Create;
  Try
    Try
      helper.Perform;
      performSomethingMore;
    finally
      helper.free
    end;
  Except
    On E:Exception Do Begin
      UndoWhateverHappened;
      MapExceptionToAbstractLayer(E)
    End;
  End;
End;
Hier werden Exceptions einer tieferen Ebene so behandelt, das erstens die Methode nach außen hin keinen Schaden anrichtet und zweitens die sehr spezifischen Exceptions der tieferen Ebene in abstraktere Exceptions gemappt werden. Es interessiert z.B. den Anwender einer abstrakten Verbindungskomponente herzlich wenig, das die TCP/IP-Addresse nicht aufgelöst werden kann, schließlich weiß er gar nicht, das die Verbindung heute mal über TCP hergestellt wird.

Die Helper-Methode "Perform" wäre nach genau dem gleichen Muster gestrickt.

Kennt jemand noch andere sinnvolle Beispiele, wo ein "Resourcenschutzblock" wirklich nötig ist?

Versteht mich bitte nicht falsch, ich bau die Dinger seit Jahren automatisch ein, aber langsam nerven die Teile, denn sie machen den Code unübersichtlich und sind zum größten Teil überflüssig:

Delphi-Quellcode:
Procedure TMyForm.Button1Click (Sender : TObject);
Var
  B : TSomething;

Begin
  B := TSomething.Create;
  Try
    B.Work;
  Finally
    B.Free
  End
End;
Ich meine, wenn es hier knallt, hab ich einfach etwas falsch gemacht. Im Umkehrschluss benötige ich also kein Try-Finally, wenn ich alles richtig gemacht habe.

Bevor man hier mit weiteren Beispielen kommt, bitte nachdenken, ob es sich nicht um o.g. Securitylayer-Implementierungen handelt...

Phoenix 12. Aug 2011 18:15

AW: Wieso Speicheranforderung in Try...Finally ?
 
Es geht primär um größere Anforderungen. Ich hatte schon das ein oder mal, wo das einfache Erzeugen einer Klasse mehr Speicher allokieren wollte (bzw. sogar musste), als das System zu diesem Zeitpunkt bereitstellen konnte. So ne OutOfMemoryException ist böse, wenn sie einem dann den kompletten Prozess abschiesst anstelle sauber abgefangen und behandelt zu werden.

Deswegen sollte man immer damit rechnen, dass die Anforderung des Speichers schief gehen kann. Wenn man damit leben kann, das einem in dem Fall die Anwendung wegbricht ist das okay. Ich will das sauber abgefangen haben ;-)

DeddyH 12. Aug 2011 18:20

AW: Wieso Speicheranforderung in Try...Finally ?
 
Ich habe das Gefühl, dass Dir der Sinn des Exception-Handlings nicht ganz klar ist. Es ist ja nicht dazu da, um Fehler, die Du durch Schusseligkeit eingebaut hast, zu beheben, sondern um Ausnahmen (eben Exceptions) abzuhandeln. Es befreit einen nicht von der Pflicht, ggf. unumgängliche Ausgangszustände im Vorfeld abzuchecken. Tritt innerhalb eines try-finally-Blocks eine Exception auf, wird ja der finally-Teil in jedem Fall durchlaufen (sogar, wenn ein exit drinsteht), der except-Teil aber nur im Ausnahmefall. Verzichtet man auf Ressourcen-Schutzblöcke, dann hat man eben im Fehlerfall das Dilemma, dass der Code zum Freigeben nicht mehr ausgeführt wird.

Luckie 12. Aug 2011 18:33

AW: Wieso Speicheranforderung in Try...Finally ?
 
Genau wie mit dem Anschnallen im Auto. Auch wenn man sich anschnallt, sollte man möglichst Unfälle versuchen zu verhindern. Und auch wenn man zu 90% unfallfrei fährt, sollte man sich doch anschnallen.

Medium 12. Aug 2011 18:36

AW: Wieso Speicheranforderung in Try...Finally ?
 
In der Fachlogik nutze ich z.B. nur try..finally, und im finally wird nach Resourcenschutz und ggf. Undos die Exception wieder geraised. In der GUI bzw. GUI-nahen Teilen dagegen wenn möglich nur try..except, um ggf. entsprechende Meldungen ausgeben zu können. Der Resourceschutz sollte möglichst komplett in der Fachlogik passiert sein, ebenso will ich keine eine ShowMessage() aus diesen jemals sehen, denn da gehören sie nicht hin.

Sinn des finally ist halt eben genau das, wie es heisst: Resourcen schützen, sprich Speicherleichen vermeiden.

stahli 12. Aug 2011 19:02

AW: Wieso Speicheranforderung in Try...Finally ?
 
@FredlFesl

In mir hast Du einen Verbündeten. Aber Du musst Dich entscheiden, ob Du Dich mit dem Rest der DP-Welt anlegen willst :-D
-> http://www.delphipraxis.net/156651-b...erklaeren.html

Würde mich dann auch mal interessieren, ob Du mein Anliegen nachvollziehen kannst (zu dem ich immer noch stehe:
-> http://www.delphipraxis.net/160164-f...ewuenscht.html
Ich würde das für ein sehr nützliches Sprach-Feature halten.
Try-Finally-Blöcke haben auch ihren Nutzen, aber m.E. in anderen Anwendungsfällen.

himitsu 12. Aug 2011 19:34

AW: Wieso Speicheranforderung in Try...Finally ?
 
Und die "Anforderung" gehört NICHT in den Schutzblock, sondern direkt davor.
Ausnahme: Die entsprechende Variable wird vorher initialisiert und am Ende überprüft+freigegeben.

Geschützt (sicher freigegeben) werden die angeforderte Sachen, nach ihrer Anforderung und nicht die Anforderung selber,
denn geht diese schief, gibt's ja auch nix zum Freigeben.

FredlFesl 12. Aug 2011 20:39

AW: Wieso Speicheranforderung in Try...Finally ?
 
Zitat:

Zitat von Phoenix (Beitrag 1116520)
Es geht primär um größere Anforderungen...

Wenn das der Fall ist, kann die Applikation sowieso nicht weiterlaufen. Und wenn nicht, tritt wieder mein bisher einziger Fall ein, bei dem ein Try-Finally Sinn macht, nämlich einen Security-Layer/Wrapper. Hier nach dem Motto: "Schaun mer mal, obs reicht. Wenn nicht, dann eben nicht". Hier würde der EOutOfMemoryException in eine andere Exception gemappt werden bzw. würde das komplett transparent gehandhabt werden.

Nochmal: Ich weiss genau, wie Exceptions funktionieren und warum. Ich behaupte nur, das es nur diesen einen Fall für Try-Finally gibt und die Vorschläge (hier und in allen anderen Foren), GRUNDSÄTZLICH jedes "Free" in einen Finally-Block zu packen, Quatsch ist.

Zitat:

Zitat von Luckie (Beitrag 1116524)
Genau wie mit dem Anschnallen im Auto. Auch wenn man sich anschnallt, sollte man möglichst Unfälle versuchen zu verhindern. Und auch wenn man zu 90% unfallfrei fährt, sollte man sich doch anschnallen.

Aber beim Unfall ist die Fahrt doch vorbei... ;-) Verstehst Du? Tritt ein Fehler auf, gehts eh nicht weiterm AUSGENOMMEN mein Beispiel.

@DeddyH: Ich meine z.B. deinen Beitrag #2 in http://www.delphipraxis.net/162202-s...ring-list.html

Diese Regel "sollten immer"... ist overkill. Die Regel muss lauten: "Wenn Du einen reentranten Zustand wieder herstellen kannst, dann tu es".

Wenn z.B. der Speicher begrenzt ist, und(!) es an der Stelle nicht weiter geht, kann ich mir Resourcenschutzblöcke echt sparen. Mit dem Beenden der Anwendung wird der Speicher eh freigegeben.

Nochmal:
Code:
MyStringList := TStringlist.Create;
Try
  MyStringList.Add('A lot of strings');
Finally
  MyStringList.Free;
End;
ist fast immer overkill.

WM_CLOSE 12. Aug 2011 20:43

AW: Wieso Speicheranforderung in Try...Finally ?
 
Was aber, wenn das Programm ständig durchlaufen soll/muss? Ein Server vielleicht, oder eine Kontrollstation der Bahn?
Was passiert dann wohl, wenn sich das Program mal so eben verabschiedet?

Luckie 12. Aug 2011 20:46

AW: Wieso Speicheranforderung in Try...Finally ?
 
Zitat:

Zitat von FredlFesl (Beitrag 1116543)
Zitat:

Zitat von Luckie (Beitrag 1116524)
Genau wie mit dem Anschnallen im Auto. Auch wenn man sich anschnallt, sollte man möglichst Unfälle versuchen zu verhindern. Und auch wenn man zu 90% unfallfrei fährt, sollte man sich doch anschnallen.

Aber beim Unfall ist die Fahrt doch vorbei... ;-) Verstehst Du? Tritt ein Fehler auf, gehts eh nicht weiterm AUSGENOMMEN mein Beispiel.

Nicht wenn dein Leben das Programm ist, dann würdest du wahrscheinlich auch sehr darauf bedacht sein, dass du nach dem Unfall weiterlebst.


Alle Zeitangaben in WEZ +1. Es ist jetzt 13:54 Uhr.
Seite 1 von 5  1 23     Letzte »    

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