![]() |
Try Finally End verlassen bzw. abbrechen
Hallo,
ich stehe vor folgendem Problem und irgendwie auf dem Schlauch: In einem sehr einfachen Programm soll beim Klick auf einen Button etwas gemacht werden. Dazu wird der Button zunächst deaktiviert und am Ende wieder aktiviert. Wenn zwischendurch etwas nicht klappt, soll der weitere Code nicht mehr ausgeführt, der Button aber wieder aktiviert werden. Um es übersichtlich zu haben, möchte ich nicht das ganze verschachteln und - weil vermutlich nicht ![]()
Delphi-Quellcode:
verzichten. Da es sich am Code vermutlich besser erklären lässt, folgendes Beispiel:
goto
Delphi-Quellcode:
Wenn Ihr mir sagt, dass es ohne
Procedure TForm1.BtnStartClick(Sender: TObject);
Const DummySpace ='C:\$space'; Begin BtnStart.Enabled:=False; MELog.Lines.Clear; Try MELog.Lines.Append('Step 1: Allocating Memory'); MELog.Lines.Append('- creating directory "' + DummySpace + '"'); If (Not CreateDir(DummySpace)) And (Not DirectoryExists(DummySpace)) Then Begin MELog.Lines.Append(' Could not create "' + DummySpace + '".'); MELog.Lines.Append(' Error was: "' + SysErrorMessage(GetLastError) + '"'); MELog.Lines.Append(' Opreation aborted.'); // Hier muss/will ich raus. End Else MELog.Lines.Append(' success...') // Hier nur weiter, wenn Verzeichnis angelegt wurde/existiert Finally BtnStart.Enabled:=True; End; End;
Delphi-Quellcode:
nicht geht, dann soll es eben so sein. Eine andere Idee wäre auch, durch eine Division durch Null eine Exception zu produzieren. Aber auch das ist nicht kunstgerecht. Das ist bestimmt total einfach und mir zugegebener Maßen schon fast peinlich diese Frage zu stellen. Aber auch Suchworte wie "abort try finally" und dergleichen brachten mich bislang nicht weiter ...
goto
Gruß, Alex |
AW: Try Finally End verlassen bzw. abbrechen
Wenn kein weiter Code nach dem
Delphi-Quellcode:
mehr kommt, dann kannst du auch einfach mit
finally-end
Delphi-Quellcode:
raus. Auch bei
Exit
Delphi-Quellcode:
werden umschließende
Exit
Delphi-Quellcode:
-Abschnitte ausgeführt.
finally
|
AW: Try Finally End verlassen bzw. abbrechen
Obwohl, sauberer wäre es, den Code einfach in den entsprechenden then bzw. else Blöcken auszuführen:
Delphi-Quellcode:
Procedure TForm1.BtnStartClick(Sender: TObject);
Const DummySpace ='C:\$space'; Begin BtnStart.Enabled:=False; MELog.Lines.Clear; Try MELog.Lines.Append('Step 1: Allocating Memory'); MELog.Lines.Append('- creating directory "' + DummySpace + '"'); If (Not CreateDir(DummySpace)) And (Not DirectoryExists(DummySpace)) Then Begin MELog.Lines.Append(' Could not create "' + DummySpace + '".'); MELog.Lines.Append(' Error was: "' + SysErrorMessage(GetLastError) + '"'); MELog.Lines.Append(' Opreation aborted.'); // Hier muss/will ich raus. End Else begin // <<<<< MELog.Lines.Append(' success...') // Hier nur weiter, wenn Verzeichnis angelegt wurde/existiert end; // <<<<< Finally BtnStart.Enabled:=True; End; End; |
AW: Try Finally End verlassen bzw. abbrechen
Du könntest natürlich auch eine Variable setzen und danach entsprechend darauf reagieren.
Oder wie wäre es wemm du den Code in entsprechende Funktionen aufteilst? :stupid: PS: "C:\$space" ... also im Grunde mag ich es absolut nicht, wenn irgenwelche Programme irgendwo einfach so rumschreiben. Wie wäre es mit dem Temp-Verzeichnis? |
AW: Try Finally End verlassen bzw. abbrechen
Hier gab es mal einige Diskussionen zu try finally:
![]() Wichtig zu wissen ist (wie Uwe schrieb), dass Exit in den finally-Block springt aber mögliche nachfolgende Anweisungen dann nichtmehr ausgeführt werden sondern die Methode verlassen wird. |
AW: Try Finally End verlassen bzw. abbrechen
Noch geschickter wäre es doch dafür ein Konstrukt zu schreiben, dass dann wie folgt benutzt werden kann:
Delphi-Quellcode:
Der TaskRunner würde per Event bei jedem Step/SubStep benachrichtigen, Exceptions fangen/protokollieren/weiterreichen (wenn gewünscht), die einzelnen Steps z.B. in einem Thread ausführen, etc.
LStep := TaskRunner.AddStep;
LStep.Caption := 'Allocating Memory'; LStep.Add( TSubStepDirectory.Create( 'C:\$space' ) ); LStep.Add( ... ); ... LStep := TaskRunner.AddStep; ... TaskRunner.Run; |
AW: Try Finally End verlassen bzw. abbrechen
Zitat:
Exit ist zum Verlassen da, aber nachfolgende umgebende Finally-Blöcke werden dennoch ordnungsgemäß abgearbeitet, denn dafür sind die ja da. Nutzloses Wissen: Wenn Exit in einer einfachen Prodedur aufgerufen wird, dann ist das ein quasi Goto zum Ende der Prozedur. Innerhalb von Try-Finally/Except, auch impliziten Try-Finally vom Delphi, welche z.B. zum Aufräumen von lokalen String-Variablen und Interfaces eingebaut wird, wird das Exit als stille Exception implementiert, welche allerdigns von Except-Blöcken automatisch "ignoriert" wird. |
AW: Try Finally End verlassen bzw. abbrechen
Zitat:
Ich schreibe übrigens auch nicht sinnlos in "C:\$space" rum. Das Programm ist eine Kreation ausschließlich für mich. Es erzeugt mehrere Dateien und trägt diese in
Delphi-Quellcode:
ein. Ein anschließendes Defragmentieren schiebt sie dann an den Anfang der Platte, so dass ich dort später dann pagefile.sys platzieren kann. Im Moment mache ich das von Hand; und das nervt sehr.
C:\Windows\Prefetch\Layout.ini
Es ist quick und dirty. Allerdings für viele Rechner und ich muss sehen, wann Fehler passieren und welche Fehler das sind. Das macht mehr Arbeit als das, was das Programm eigentlich machen soll. So. Und jetzt muss ich bloß noch suchen, wie ich Windows oder dem Programm beibringe, dass beim Start gleich die Abfrage nach Admin-Rechten kommt für Schreibrechte in "C:\Windows\Prefetch". Aber das bekomme ich auch bald raus. Wie gesagt: tausend Dank. Alex P.S. Wo muss ich jetzt vermerken, dass die eigentliche Frage des Themas gelöst ist? |
AW: Try Finally End verlassen bzw. abbrechen
zum PS: Einfach schweigen reicht ... ;-)
|
AW: Try Finally End verlassen bzw. abbrechen
Zitat:
|
AW: Try Finally End verlassen bzw. abbrechen
Ich habe das missverständlich formuliert.
Verbale Rückmeldung und Ruhen lassen des Threads reicht aus. Ein Erledigt-Flag oder Abschließen des Threads ist nicht notwending. |
AW: Try Finally End verlassen bzw. abbrechen
Ein Manifest welches ensprechende (Admin)Rechte anfordert,
oder ein externer Aufruf z.B. über Runas, oder über Eigenschaften von Verknüpfungen (lnk), oder der zugeordnete Benutzerkonto eines Services usw. Wenn man das unbedingt markieren will, dann kann man beim Erstellen einer Frage diese als "offen" markieren und das später wieder weg machen, oder schreibt einfach, daß und eventuell welche Lösung man genommen hat. |
AW: Try Finally End verlassen bzw. abbrechen
Ich würde das so lösen:
Delphi-Quellcode:
Procedure TForm1.BtnStartClick(Sender: TObject);
Const DummySpace ='C:\$space'; Procedure _DemandDirectoryCreated(string aDirectory); Begin CreateDir(aDirectory); if Not DirectoryExists(aDirectory) Then Abort; end; Begin BtnStart.Enabled:=False; MELog.Lines.Clear; Try MELog.Lines.Append('Step 1: Allocating Memory'); MELog.Lines.Append('- creating directory "' + DummySpace + '"'); _DemandDirectoryCreated(DummySpace); MELog.Lines.Append(' success...'); // Hier nur weiter, wenn Verzeichnis angelegt wurde/existiert Except MELog.Lines.Append(' Could not create "' + DummySpace + '".'); MELog.Lines.Append(' Error was: "' + SysErrorMessage(GetLastError) + '"'); MELog.Lines.Append(' Opreation aborted.'); End; BtnStart.Enabled:=True; End; |
AW: Try Finally End verlassen bzw. abbrechen
@Dejan Vu
Das kann evtl. funktionieren, allerdings muss der Aufruf von
Delphi-Quellcode:
direkt im Anschluss der Funktion aufgerufen werden, wo dieser Fehler (hier
GetLastError
Delphi-Quellcode:
) aufgetreten ist.
CreateDir
Ansonsten ist nicht gewährleistet, dass man auch wirklich die Fehlermeldung bekommt, die man eigentlich haben möchte. EDIT Eigentlich arbeitet
Delphi-Quellcode:
nur dann zuverlässig, wenn man gesichert direkt vorher eine Windows-Funktion aufgerufen hat.
GetLastError
Bei ![]()
Delphi-Quellcode:
type
// Wenn ein Arbeitsschritt fehlschlägt, dann diese Exception werfen EStepException = class(Exception); procedure TForm1.BtnStartClick( Sender : TObject ); begin BtnStart.Enabled := False; try try MELog.Lines.Append('Step 1: Allocating Memory'); MELog.Lines.Append('- creating directory "' + DummySpace + '"'); if ForceDirectories( DummySpace ) then MELog.Lines.Append( ' success' ) else raise EStepException.CreateFmt( 'Could not create "%s"', [DummySpace] ); // nächste Schritte except on E: EStepException do begin MELog.Lines.Append( E.Message ); MELog.Lines.Append( 'Operation aborted.' ); raise; end; end; finally BtnStart.Enabled := True; end; end; |
AW: Try Finally End verlassen bzw. abbrechen
Zitat:
Leider ist Delphi da noch nicht konsequent und bietet durchweg Methoden an, die knallen, anstatt einen Rückgabewert zu liefern. Dann dadurch wird man ja gerade dazu verleitet, IF-THEN-Verschachtelngsorgien zu 'feiern'. Gehört hier aber nicht hin. |
AW: Try Finally End verlassen bzw. abbrechen
Exceptions sind nicht zur standardmäßigen Flusssteuerung vorgesehen und vorallem beim Debuggen fällt man mit soeinem Schrott einfach nur voll auf die Fresse.
Wobei hier das ja auch als Ausnahme gesehen werden kann, wenn man auf das Verzeichnis nicht zugreifen kann und demnach nachfolgene Operationen, welche ja die Hauptfunktionalität darstellen, nicht mehr ausführbar sind. |
AW: Try Finally End verlassen bzw. abbrechen
Zitat:
Edit: 'standardmäßigen' ist das Zauberwort. Da hast Du recht. Aber es war ein ungünstiger Kommentar zu einem imho legitimen Einsatz von Exceptions. Ich bezeichne das als happy path programming. Der Kontrollfluß zeigt, wie es im Normalfall (der happy path) aussieht und die Ausnahmen hüpfen einfach raus (bzw. in den Except/Finally Teil). |
AW: Try Finally End verlassen bzw. abbrechen
Zitat:
|
AW: Try Finally End verlassen bzw. abbrechen
Der Fall, das ein Verzeichnis nicht angelegt werden kann und nicht existiert, ist meiner Meinung nach eine ziemliche Ausnahme (abgesehen von merkwürdigen Ordner-Namen oder nicht existierenden Eltern-Ordnern, die sollte man vielleicht vorher abfangen).
Außerdem wird die Operation abgebrochen und ein Log-Eintrag dazu angelegt. Was muss noch alles dazu kommen, das eine Exception gerechtfertigt ist? Random Memory Corruption? :mrgreen: |
AW: Try Finally End verlassen bzw. abbrechen
Zitat:
Zitat:
|
Alle Zeitangaben in WEZ +1. Es ist jetzt 20:54 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