…Finally…

Exception Handling ist für einige Entwickler immer noch ein Mysterium. try…catch haben die Meisten zwar schon einmal gesehen und der ein oder andere hat sogar schon einen Finally-Block gesehen, aber viele können damit nicht richtig umgehen. Insbesondere der Sinn und Zweck des Finally-Blocks lässt dem ein oder anderen ein Fragezeichen über der Stirn erscheinen. Genau diese Gruppe von Personen möchte ich mit diesem Artikel erreichen und versuchen, daß Fragezeichen aufzulösen. Aber auch der fortgeschrittene Entwickler kann vielleicht die ein oder andere Kleinigkeit aus diesem Beitrag ziehen.

Als kurze Einleitung hier mal ein Stück Pseudocode (das C# absichtlich sehr ähnlich ist) um noch einmal zu zeigen, wie ein try…catch…finally-Block aussieht. Ich werde zu einem späteren Zeitpunkt noch einen ausführlicheren Artikel schreiben, der detaillierter auf das Exception-Handling eingehen wird. Diesen werde ich dann hier verlinken. (Nachtrag vom 02.02.2011: Artikel Exception Handling)

try
{
  // Code, in dem Exceptions auftreten können
}
catch (Exception e)
{
  // Ausnahmebehandlung
}
finally
{
  // wird in jedem Fall ausgeführt
}
// weitere Statements, die nicht in jedem Fall ausgeführt werden

Der Finally-Block wird ausgeführt, egal ob:

  • der Try-Block vorzeitig verlassen wird (exit, break, continue, return)
  • die Exception im Catch-Block an die aufrufende Stelle weitergeleitet wird
  • der Catch-Block vorzeitig verlassen wird (exit, break, continue, return)
  • alles ganz normal abläuft

Die Statements nach dem try…catch…finally-Block werden nur dann ausgeführt, wenn im Try- oder Catch-Block die Ausführung nicht an eine andere Stelle übergeben wird.

Der Finally-Block kann also dazu verwendet werden, um Aufzuräumen, z.B. wenn im Try-Block eine Datei geöffnet wurde, oder mit lock andere Threads blockiert wurden.

Ein schönes Beispiel ist folgendes:

public bool ReadScores()
{
  FileStream stream;
  byte[] content;

  try
  {
    stream = System.IO.File.OpenRead(@"highscore.dat");
    stream.Read(content, 0, 10);
  }
  catch (IOException e)
  {
    // der Stream ist unerwartet zuende, es konnten also keine 10 Bytes gelesen werden
    // Default-Werte erzeugen
    return false;
  }
  catch (FileNotFoundException e)
  {
    // die Datei wurde nicht gefunden oder ist verschwunden
    // Fehlermeldung anzeigen
    return false;
  }
  finally
  {
    stream.Close();
  }

  return true;
}

Diese imaginäre Methode ReadScores liest ein Highscore-File von einem Speichermedium. Dabei können selbstverständlich Fehler auftreten. In diesem Beispiel werden exakt zwei Fehler abgefangen:

  • Nicht genug Daten in der Datei (IOException)
  • Datei nicht gefunden (FileNotFoundException)

Nach dem Lesen wird die Datei natürlich ordnungsgemäß geschlossen (Zeile 25). Dies erfolgt in einem Finally-Block. Dies hat den Sinn, daß dieser Befehl in jedem Fall ausgeführt werden muss. Tritt beispielsweise in Zeile 9 eine Exception auf (es können nicht genug Bytes gelesen werden), so erzeugt das Programm im entsprechenden Catch-Block (ab Zeile 11) Default-Werte und beendet die Funktion durch Rückgabe eines False-Wertes.

Genau hier tritt das Problem auf. Der FileStream ist noch offen. Würde man das Programm wie folgt schreiben

public bool ReadScores()
{
  FileStream stream;
  byte[] content;

  try
  {
    stream = System.IO.File.OpenRead(@"highscore.dat");
    stream.Read(content, 0, 10);
  }
  catch (IOException e)
  {
    // der Stream ist unerwartet zuende, es konnten also keine 10 Bytes gelesen werden
    // Default-Werte erzeugen
    return false;
  }
  catch (FileNotFoundException e)
  {
    // die Datei wurde nicht gefunden oder ist verschwunden
    // Fehlermeldung anzeigen
    return false;
  }

  stream.Close();

  return true;
}

so würde im Fehlerfall der Stream nicht wie vorgesehen in Zeile 24 geschlossen.

Wie man sieht, hilft Finally also dabei, Programme zu strukturieren, übersichtlich zu gestalten und ein definiertes Verhalten zu erzielen.

Advertisements

Veröffentlicht am 05.12.2010 in C#, Grundlagen und mit , , , , , , getaggt. Setze ein Lesezeichen auf den Permalink. 2 Kommentare.

  1. Artikel zum Thema Exception Handling wurde mittlerweile geschrieben: Exception Handling

  1. Pingback: Exception Handling « "Mit ohne Haare"

Kommentar verfassen

Trage deine Daten unten ein oder klicke ein Icon um dich einzuloggen:

WordPress.com-Logo

Du kommentierst mit Deinem WordPress.com-Konto. Abmelden / Ändern )

Twitter-Bild

Du kommentierst mit Deinem Twitter-Konto. Abmelden / Ändern )

Facebook-Foto

Du kommentierst mit Deinem Facebook-Konto. Abmelden / Ändern )

Google+ Foto

Du kommentierst mit Deinem Google+-Konto. Abmelden / Ändern )

Verbinde mit %s

%d Bloggern gefällt das: