AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Programmierung allgemein Programmieren allgemein Verständnisfrage zu try-except-finally
Thema durchsuchen
Ansicht
Themen-Optionen

Verständnisfrage zu try-except-finally

Ein Thema von BAMatze · begonnen am 29. Apr 2009 · letzter Beitrag vom 29. Apr 2009
Antwort Antwort
Seite 1 von 2  1 2      
BAMatze

Registriert seit: 18. Aug 2008
Ort: Berlin
759 Beiträge
 
Turbo Delphi für Win32
 
#1

Verständnisfrage zu try-except-finally

  Alt 29. Apr 2009, 14:22
Hallo an alle DPler,

Hab eine Frage zu try-except-finally. Also ich habe schon sehr erfolgreich try-except-Abfragen in meinem Projekt eingebaut und alles lief wunderbar. Hier mal ein kleines Beispiel:

Delphi-Quellcode:
function TControlerBoard.anaAusgang_einschalten: boolean;
begin
  try
    if sKameraposition = 'obenthen
      begin
        OutputAnalogChannel(1,Diodenhelligkeit[1]);
        anaAusgang_ausschalten(2);
      end
    else
      begin
        OutputAnalogChannel(2,Diodenhelligkeit[2]);
        anaAusgang_ausschalten(1);
      end;
    result := true
  except
    // Fehlermeldung
    result := false;
  end;
end;

function TControlerBoard.anaAusgang_ausschalten(iNummer: Integer): boolean;
begin
  try
    ClearAnalogChannel(iNummer);
    result := true
  except
    // Fehlermeldung
    result := false;
  end;
end;

function TControlerBoard.alle_anaAusgeange_ausschalten;
begin
  try
    ClearAllAnalog;
    result := true
  except
    // Fehlermeldung
    result := false;
  end;
end;
Sind ein paar Funktionen für ein Controler-Board und wie gesagt, bin sehr zufrieden damit. Jetzt versuche ich in meiner Komponente ebenfalls eine try-except-Abfrage zu machen und bekomme trotz das ich den eigentlichen Fehlerpunkt damit "umschließe" immer eine Fehlermeldung und ich weiß einfach nicht, warum dies der Fall ist.

Hier meine derzeitige Routine an der ich arbeite.
Delphi-Quellcode:
procedure TContainer.Beschleunigungmanuellverlassen(Sender: TObject; var Key: Word;
  Shift: TShiftState);
var Index: integer;
    dWert: double;
begin
  if Key = 13 then
    begin
      try
        dWert := strtofloat(FEdmanuelleBeschleunigungsEingabe.Text) // <-- Hier tritt der Fehler auf
      except
        Showmessage('Hier');
      end;
    end;
end;
Hab die Stelle markiert, wo der Fehler auftreten kann. Eigentlich, so aus meinem Verständnis heraus, sollte das Programm, wenn dWert nicht eine Gleitkomma-Zahl übergeben wird in die Except-Fkt springen und mir somit ein "Hier" ausgeben. Er meldet mir aber, dass in dem Edit (FEdmanuelleBeschleunigungsEingabe) dies nicht der Fall ist (es steht dort wirklich keine Gleitkomma drin!) was also richtig ist. Wie gesagt, eigentlich erwarte ich eigentlich, dass die Exception nicht auftritt und er mir statt dessen Die Showmessage zeigen sollte.
Kann mir das jemand mal erklären, warum dies in dem Fall so ist?

PS.: ich weiß mit der trystrtofloat könnte ich dieses ganze Problem umgehen, indem ich eine if-Abfrage starte aber wenn ich dies tun würde, dann wäre die try-Except-Abfrage in meinem bisherigen Verständnis der Problematik überflüssig, da ich alles mit if abfragen abfangen kann (in einem gewissen größeren Rahmen sicherlich).

Vielen Dank
BAMatze
  Mit Zitat antworten Zitat
TheFrog

Registriert seit: 24. Mär 2009
145 Beiträge
 
Delphi 11 Alexandria
 
#2

Re: Verständnisfrage zu try-except-finally

  Alt 29. Apr 2009, 14:29
Kann es sein, dass du unter Tools --> Debugger-Optionen --> Sprach-Exceptions die Option "Bei Delphi-Exceptions stoppen" aktiviert hast und die Anwendung aus der IDE heraus startest?

Hans.
  Mit Zitat antworten Zitat
Benutzerbild von sirius
sirius

Registriert seit: 3. Jan 2007
Ort: Dresden
3.443 Beiträge
 
Delphi 7 Enterprise
 
#3

Re: Verständnisfrage zu try-except-finally

  Alt 29. Apr 2009, 14:31
Ergänzung zu roter Kasten:

Du hast aber nicht übersehen, dass beim ausführen des Programmes in der IDE das Programm immer bei jedem Fehler angehalten wird. Erst danach erfolgt eine mögliche Excpetionbehandlung.

Also: Innerhalb der IDE kommt erst der Stop beim Fehler selbst und dann was in Except steht. Außerhalb der IDE passiert nur, was in Except steht.
Dieser Beitrag ist für Jugendliche unter 18 Jahren nicht geeignet.
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu
Online

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
44.063 Beiträge
 
Delphi 12 Athens
 
#4

Re: Verständnisfrage zu try-except-finally

  Alt 29. Apr 2009, 14:33
Wer dir hier die Exception meldet, ist der Debugger ... starte mal dein Programm außerhalb der Delphi-IDE oder schalte die entsprechenden Meldungen ab.

aber zumindestens im Fertigen Programm (ohne daß es im Debugger läuft) wird die Exception nicht mehr angezeigt.

PS: TryStrToFloat hätte noch einen Vorteil, denn dieses wirft erst garkeine Exception, welcher sich erstmal durch's halbe Programm frißt (Exceptions sind 'ne größere Angelegenheit und da läuft einiges im Hintergrund ab, welches natürlich auch Rechenzeit frißt und dazu noch den Code etwas vergrößert)
Neuste Erkenntnis:
Seit Pos einen dritten Parameter hat,
wird PoSex im Delphi viel seltener praktiziert.
  Mit Zitat antworten Zitat
BAMatze

Registriert seit: 18. Aug 2008
Ort: Berlin
759 Beiträge
 
Turbo Delphi für Win32
 
#5

Re: Verständnisfrage zu try-except-finally

  Alt 29. Apr 2009, 14:42
Ja das Häckchen war es.

Wäre aber jetzt eine Folgefrage: Was sollte man wo setzen? Ich meine in diesem Fall würde ich warscheinlich die trystrtofloat-Abfrage bevorzugen, da ich aufgrund der Kürze des Programmcodes mit keinen weiteren Fehlern rechnen müsste (Der Fehler ist somit qualifizierbar). Gibt es da vieleicht (für einen Anfänger wie mich) so grundsätzliche Regeln für den Einsatz von try-except-finally, die zu einer gewissen Warscheinlichkeit immer greifen, so dass man nur noch die Ausnahmen behandeln muss oder ist das eher eine Philosophy, die sich ein jeder Programmierer oder Benutzer einer Programmiersprache selber erfinden muss?
  Mit Zitat antworten Zitat
shmia

Registriert seit: 2. Mär 2004
5.508 Beiträge
 
Delphi 5 Professional
 
#6

Re: Verständnisfrage zu try-except-finally

  Alt 29. Apr 2009, 14:58
Du benützt try..except auf eine ganz falsche Art und Weise!!
Früher, als es noch keine Exceptions gab, hat man Fehler fast immer über einen Returncode zurückgeliefert.
Delphi-Quellcode:
function BerechneIrgendwas:integer;
begin
  ...
  if zins < 0.0 then
  begin
    result := ERROR_CODE_ZINS_FALSCH;
    Exit;
  end;
  ...
end;
Man kann dies noch etwas vereinfachen, in dem man als Returncode nur True oder False zurückliefert.
Natürlich ist die Technik einen Fehler über einen Boolean zurückzumelden (so wie du das in TControlerBoard.anaAusgang_einschalten tust) das Schlechteste was man tun kann.
Grund: die Ursache des Fehler bleibt für immer im Dunkeln

Und jetzt kommt die Technik der Exceptions in Spiel.
Jetzt man man sinnvolle Fehlermeldungen zurückliefern, anstatt nur Fehlercodes oder nur die Info "Geht" oder "Geht nicht".
Richtig blöd wird es aber, wenn man eine Exception mit sinnvoller Fehlermeldung (z.B. "COM-Port 1 kann nicht geöffnet werden")
mit try...except abfängt und daraus einen Boolean-Returncode produziert.

Weiterer Lesestoff:
http://www.delphipraxis.net/internal...ct.php?t=30241
Andreas
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu
Online

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
44.063 Beiträge
 
Delphi 12 Athens
 
#7

Re: Verständnisfrage zu try-except-finally

  Alt 29. Apr 2009, 15:02
also wenn dein Programm nach der Exception noch 'ne Weile ordentlich weiterlaufen soll, dann dort, wo du etwas schützen mußt >>> Resourcenschutzblock

Delphi-Quellcode:
// hier Speicher reservieren / etwas sperren oder sonstwas,
// was auf jeden Fall rückgängig gemacht werden muß
Lock; oder X:=GetMem; oder Y:=Z.Create;
try
  //hier was machen
finally
  // und hier den Speicher freigeben oder die Sperre aufheben
  Unlock; oder FreeMem(X); oder Y.Free;
end;
oder wenn du selber auf die Exception reagieren willt, um stattdessen etwas Alternatives zu machen
Delphi-Quellcode:
try
  // mach was
except
  // mach stattdessen was Anderes
end;
Es ist garnicht möglich wirklich auf alles zu reagieren, also besinn dich nur auf das "Nötigste", dann bleibt dein Code auch übersichtlicher.
in nochmalen VCL-Anwendungen (nicht in einer Konsolenanwendung) ist eh nahezu jeder Prozeduraufruf seitens der VCL (also z.B. Ereignisprozeduren) mit einem Try-Except abgesichert, so daß nicht gleich das ganze Programm verreckt, wenn mal was passiert.


PS: in meinem aktuellen Projekt (Hier im Forum suchenhimXML) fang ich absichtlich fast garkeine Exceptions ab (und wenn, dann wandle ich die meißt in eigene Exceptions um), leite alles nach Außen hin weiter und erzeuge notfalls sogar selber Exceptions.
Ich sorge meist nur mit einem Try-Finally daß möglichst keine Speicherlecks entstehen. (kannst dich da gern mal umsehen)

So kann man im aufrufendem Code besser reagieren und man erfährt auch was und wo es geknallt hat ... denn wenn es knallt, dann hat das 'nen Grund und den gilt es zu finden und zu beheben, anstatt alles unter den Teppisch zu kehren.

PSS: meinen Hier im Forum suchenFileSplitter hab ich damals ganz ohne Try-Except/Finally programmiert, denn diese sing garnicht immer nötig, wenn man die Fehler vorher abfängt (also bevor es knallt) und man weiß was man tut und was passieren könnte bzw. was nicht passiert.
Neuste Erkenntnis:
Seit Pos einen dritten Parameter hat,
wird PoSex im Delphi viel seltener praktiziert.
  Mit Zitat antworten Zitat
BAMatze

Registriert seit: 18. Aug 2008
Ort: Berlin
759 Beiträge
 
Turbo Delphi für Win32
 
#8

Re: Verständnisfrage zu try-except-finally

  Alt 29. Apr 2009, 15:36
Also schonmal ein Dankeschön an shmia und himitsu für die doch recht ausführlichen Erklärungen über try Except.

@shmia
Ich hab mir deinen Lesestoff mal zu Gemüte geführt und es ist auch sehr informativ. Habe auch glaube ich ein paar Prozeduren genommen, wo ich für mich selber festgestellt habe, dass auch wenn die Aufrufe ins Nirvana gehen (z.B. wenn die Karte gar nicht angeschlossen ist) gar keine Exception erzeugen. Bin mir bei diesen Proceduren auch noch nicht sicher, ob ich dann die Exceptions drin lassen sollte oder sie wieder rausnehme.

Habe hier mal ein anderen Programmteil aus dem Projekt genommen und würde gern mal eure Meinung dazu hören, ob sinnvoll oder ob nicht sinnvoll oder vieleicht Verbesserungen möglich wären. Ich bitte dabei zu beachten, dass es sich dabei um meinen ersten Versuch handelt, mit Exceptions umzugehen und Fehlercodes in mein Programm einzubauen.

Delphi-Quellcode:
function TControlerBoard.DLLHandle_zuweisen: boolean;
begin
  //Protokoll.Protokolleingang('ControlerBoard', 'DLLHandle-Fkt');
  Fehlermeldung(300);
  try
    ControlerDLL := TDLL_Datei.create('K8055D.DLL');
    if ControlerDLL.Vorhanden then
      begin
        DLL_Handle := ControlerDLL.Handle;
        result := true;
      end
    else
      begin
        Fehlermeldung(301);
        DLL_Handle := 0;
        result := false;
      end
  except
    Fehlermeldung(302);
    result := false;
  end;
  //Protokoll.Protokollausgang('ControlerBoard', 'DLLHandle-Fkt');
end;

function TControlerBoard.DLLFunktionen_laden: boolean;
begin
  //Protokoll.Protokolleingang('ControlerBoard', 'DLL-Fkt laden');
  try
    if DLL_Handle <> 0 then
      begin
        @OpenDevice := GetProcAddress(DLL_Handle, 'OpenDevice');
        @CloseDevice := GetProcAddress(DLL_Handle, 'CloseDevice');
        @ClearAllAnalog := GetProcAddress(DLL_Handle, 'ClearAllAnalog');
        @ClearAllDigital := GetProcAddress(DLL_Handle, 'ClearAllDigital');
        @ClearAnalogChannel := GetProcAddress(DLL_Handle, 'ClearAnalogChannel');
        @ClearDigitalChannel := GetProcAddress(DLL_Handle, 'ClearDigitalChannel');
        @OutputAnalogChannel := GetProcAddress(DLL_Handle, 'OutputAnalogChannel');
        @SetDigitalChannel := GetProcAddress(DLL_Handle, 'SetDigitalChannel');
        @ReadDigitalChannel := GetProcAddress(DLL_Handle, 'ReadDigitalChannel');
        result := true;
      end
    else
      begin
        Fehlermeldung(303);
        result := false;
      end
  except
    Fehlermeldung(304);
    result := false;
  end;
  //Protokoll.Protokollausgang('ControlerBoard', 'DLL-Fkt laden');
end;

function TControlerBoard.Initialising:boolean;
begin
  try
    if (DLLHandle_zuweisen = true) and (DLLFunktionen_laden = true) then
      begin
        OpenDevice(0);
        ClearAllDigital;
        {Liste der einzuschaltenen Geräte per Funktion hier einfügen}
        V_Tische_Stromversorgung_einschalten;
        P_Tisch_Stromversorgung_einschalten;
        Spleissgeraet_einschalten;
        result := true;
      end
    else
      begin
        Fehlermeldung(305);
        result := false;
      end
  except
    Fehlermeldung(306);
    result := false;
  end;
end;
Ok ich denke, da ich fast alle Units ähnlich wie diese aufgebaut habe, ist die Vorgehensweise erkennbar. Die "Fehlermeldung(...)" ist dabei für mich eine Meldefunktion an eine Fehlerklasse, die anhand der Nummer den auftretenden Fehler zum Teil genau aber in einigen Fällen auch nur in einem gewissen Rahmen qualifiziert. In der Fehler-Klasse werden die übergebenen Nummern interpretiert und dann in eine Fehler-Log-Datei eingeschrieben. Bisher bin ich mit der Methode eigentlich zu frieden, da ich darüber mein Programm auch wenn bestimmte Geräte (wie z.B. die Controler-Board-Karte) nicht angeschlossen sind, starten kann und über den Status im Programm der Bediener mitbekommt, was genutzt werden kann und was er vieleicht doch nochmal einschalten muss oder was nicht funktioniert.

Über konstruktive Kritik würde ich mich sehr freuen.
  Mit Zitat antworten Zitat
BAMatze

Registriert seit: 18. Aug 2008
Ort: Berlin
759 Beiträge
 
Turbo Delphi für Win32
 
#9

Re: Verständnisfrage zu try-except-finally

  Alt 29. Apr 2009, 18:06
Keiner eine Meinung?
  Mit Zitat antworten Zitat
Benutzerbild von DeddyH
DeddyH

Registriert seit: 17. Sep 2006
Ort: Barchfeld
27.624 Beiträge
 
Delphi 12 Athens
 
#10

Re: Verständnisfrage zu try-except-finally

  Alt 29. Apr 2009, 18:18
Exceptions kannst Du nur da abfangen, wo auch welche geworfen werden. GetProcAddress z.B. gehört nicht dazu, bei Misserfolg ist der Funktionszeiger dann eben nil. Außerdem bedeutet Exception Ausnahme, d.h. das sind Fehler, die nur unter besonders ungünstigen Bedingungen auftreten können (Abbruch der Netzwerkverbindung, nicht genügend Festplattenplatz, kein Datenträger im Laufwerk oder etwas in der Art) und auf die Du keinen Einfluss hast. Alle durch Dich vermeidbaren Fehlerquellen solltest Du schon programmatisch abfangen.
Detlef
"Ich habe Angst vor dem Tag, an dem die Technologie unsere menschlichen Interaktionen übertrumpft. Die Welt wird eine Generation von Idioten bekommen." (Albert Einstein)
Dieser Tag ist längst gekommen
  Mit Zitat antworten Zitat
Antwort Antwort
Seite 1 von 2  1 2      


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 15:01 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