WCM Forum

WCM Forum (http://www.wcm.at/forum/index.php)
-   Programmierung (http://www.wcm.at/forum/forumdisplay.php?f=17)
-   -   try, catch, ...finally (http://www.wcm.at/forum/showthread.php?t=119613)

Biri 23.12.2003 10:55

try, catch, ...finally
 
hi !

Ich lese im moment gerade eine paar prüfungsbeispiele für den MCAD.
Dort gibt es folgendes Beispiel:

try
{
Debug.WriteLine(“Inside Try”);
throw(new IOException());
}
catch (IOException e)
{
Debug.WriteLine (“IOException Caught”);
}
catch (Exception e)
{
Debug.WriteLine(“Exception Caught”);
}
finally
{
Debug.WriteLine (“Inside Finally”);
}
Debug.WriteLine (“After End Try”);


Welche Ausgabe erzeugt der code ?

A.
Inside Try
Exception Caught
IOException Caught
Inside Finally
After End Try

B.
Inside Try
Exception Caught
Inside Finally
After End Try

C.
Inside Try
IOException Caught
Inside Finally
After End Try

D.
Inside Try
IOException Caught
Inside Finally

Antowrt: D

Explanation: First the try code runs. Then one single exception occurs, not two.
Then the finally code is run, and not the code after finally.

Reference: 70-306/70-316 Training kit, Creating an Exception handler, page 235

Incorrect Answers
A: An exception can only be caught once, not twice.
B: The code after finally will not be run if an exception occurs.
C: The code after finally will not be run if an exception occurs.

Das stimmt aber nicht !
Wenn man das Beispiel im VS.Net ausprobiert, wird der code NACH finally immer ausgeführt.
Dadurch stellt sich dann aber die frage: wozu benötigt man finally überhaupt ??

Was sagt Ihr dazu ?

fg
-hannes

(V)uh 23.12.2003 12:07

Lt. .Net hilfe spielt sich das so ab ...

Der finally-Block ist für das Bereinigen aller Ressourcen nützlich, die im "try"-Block reserviert sind. Die Steuerung wird immer an den finally-Block übergeben, unabhängig davon, wie der try-Block beendet wird. Die Anweisung hat das folgende Format:

try try-block finally finally-block
Hierbei ist:

try-block
der Anweisungsblock, der das Codesegment enthält, das aller Erwartung nach die Ausnahme auslöst.
finally-block
der Anweisungsblock, der den Ausnahmebehandler und den Bereinigungscode enthält.


Ergo: finally wird anscheinend immer ausgeführt und dient zum rückstellen irgendwelcher einstellungen. Demnach sollte C die richtige lösung sein denke ich.

Biri 23.12.2003 12:11

genau das meine ich (u.d. compiler) ja auch !
Aber ist das nicht bedenklich, wenn in einem Lehrbuch mit den Testfragen für dem MCAD etwas anderes steht ?
...und als Quelle dafür das MS-Training Kit angegeben wird ?

in der msdn hilfe findet man nix dazu - da hören die programme immer nach finaly auf.

thx+fg
-hannes

(V)uh 23.12.2003 12:17

Vielleicht gibz ja bald ein update der trainingsunterlagen :lol: aber nicht mehr in diesem jahr, denn MS hat ja alle updates für dieses jahr gestoppt :D
Ich denke auch, dass sich da ein fehler eingeschlichen hat in den unterlagen, aber vielleicht postet ja noch wer was und belehrt uns eines besseren.

käptn 23.12.2003 12:30

Ich würd' sagen dass die Anweisungen nach dem "finally" Block nicht ausgeführt werden, falls die Ausnahme nicht abgefangen wird.

~

Biri 23.12.2003 15:45

hi !

@käptn: genau so ist es - das hab ich ebenfalls probiert:
nur ein try {} in diesem ein throw... - kein catch - dann wird nur der code im finaly ausgeführt.

aber:
1. welchen sinn hat das ? (eine exception NICHT abzufangen)
2. das MS-Beispiel ist falsch (inho - und das hat mich ja gewundert)
3. punkt 2 gibt mir zu denken, weil ich überlege, den mcad zu machen.

bissl abseits des themas: ;)

4. haltet ihr punkt 3 für empfehlenswert ?

fg
-hannes

Sesa_Mina 23.12.2003 15:55

Also rein vom logischen Ablauf wäre C hier richtig. Die exception wird ja abgefangen und verarbeitet.

Biri 23.12.2003 16:00

@sensa_mina: beziehst du das auf den beispielcode ?

dieser ist natürlich korrekt - aber darauf bezog sich eigentlich nicht meine frage...

fg
-hannes

Who-T 24.12.2003 00:49

Zitat:

Original geschrieben von Biri
1. welchen sinn hat das ? (eine exception NICHT abzufangen)
du schreibst eine library. du kannst dich um einige fehler selber kümmern, aber manche musst du einfach weiterleiten

zb:
du hast eine methode die dir auf eine hardware zugreift und dir zb ein register ausliest und zurückgibt

das ganze wär dann

public int readRegister ();

nur - was machst du wenn die hardware net angeschlossen ist?
das musst du irgendwie mitteilen können. den rückgabewert hierfür verändern ist schlecht (zb -1 als rückgabewert, könnte ja auch der wert des registers sein)
deshalb leitest du alle exceptions, die anzeigen dass die HW net verfügbar ist weiter

zb
Code:

public itn readRegister () throws TimeoutException
{
  // connect
  try
  {
    connectToHardware();
  } catch (IOException e) // we can handle IO exception, we know a different way to connect
  {
    tryDifferentConnection();
  }
 
  int i = readfromregister(); // could throw timeout
  // if timeout occurs it's not caught
  // since we should be connected a timeout only means
  // that there is no hardware availiable

  return i;

}


ich hoff das beispiel war halbwegs verständlich

Biri 24.12.2003 09:00

@Who-T: Danke !!
auf sowas habe ich nicht gedacht - jetzt ist mir der sinn natürlich klar. (ist wieder eins von den dingen, die einem im nachhinein betrachtet dann voll logisch vorkommen).

Hab noch ein kleines Beispielprogramm geschreiben - der Vollständigkeit halber:

Code:

                //
                // Funktion 1 erzeugt eine Exception, die nicht abgefangen wird
                // in diesem Fall wird dann der Code bei Finally durchgeführt und
                // die Funktion beendet.
                //
                // Grund: Es kann sein, dass man nicht alle auftretenden Excetions
                //        in der Funktion bearbeiten kann !
                //
                // Die Exception sollte dann jedoch im Hauptprogramm (bzw. der
                // aufrufenden Funktion abgefangen werden.
                //
                static public void funktion1()
                {
                        try
                        {
                                MessageBox.Show("Try - Funktion 1");
                               
                                // nach diesem throw (der in der Fu. nicht verarbeitet wird),
                                // wird sofort der "finally" Zweig (und nichts sonst)
                                // ausgeführt
                                throw new NullReferenceException();
                        }
                        catch(IOException ex)
                        {
                                MessageBox.Show("IO-Excpetion caught - Funktion 1");
                        }
                        finally
                        {
                                MessageBox.Show("Finally Block - Funktion 1");
                        }

                        MessageBox.Show("Ende der Funktion 1");
                }


                //
                // In dieser Funktion wird die "Funktino 1" aufgerufen und
                // die Exceptions, die in der Funktion nicht behandlet werden, behandelt
                //
                private void button1_Click(object sender, System.EventArgs e)
                {
                        try
                        {
                                MessageBox.Show("Try der aufrufenden Funktion");
                                funktion1();
                        }
                        catch (NullReferenceException ex)
                        {
                                MessageBox.Show ("NullReferenceException caught - aufrufende Funktion");
                        }
                        // Hier werden ALLE Exceptions verarbeitet
                        catch (Exception ex)
                        {
                                MessageBox.Show("Exception caught - aufrufende Funktion");
                        }
                        finally
                        {
                                MessageBox.Show ("Finally - aufrufende Funktion");
                        }

                        MessageBox.Show ("Ende - aufrufende Funktion");
                }

Ausgabe:
--------
Try der aufrufenden Funktion
Try - Funktion 1
Finally Block - Funktion 1
NullReferenceException caught - aufrufende Funktion
Finally - aufrufende Funktion
Ende - aufrufende Funktion


Danke an alle + schöne, erholsame Feiertage !
-hannes


Alle Zeitangaben in WEZ +2. Es ist jetzt 16:53 Uhr.

Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
© 2009 FSL Verlag