Behandeln und Auslösen von Ausnahmen

Anwendungen müssen in der Lage sein, Fehler zu behandeln, die während der Ausführung konsistent auftreten. Die Common Language Runtime verfügt über ein Modell zur einheitlichen Fehlerbenachrichtigung für Anwendungen. Alle Operationen in .NET Framework zeigen Fehler durch Auslösen von Ausnahmen an.

Dieses Thema enthält folgende Abschnitte:

  • Ausnahmen in .NET Framework

  • Ausnahmen im Vergleich zu herkömmlichen Fehlerbehandlungsmethoden

  • Verwalten von Ausnahmen durch die Common Language Runtime

  • Filtern von Laufzeitausnahmen

  • Verwandte Themen

  • Verweis

Ausnahmen in .NET Framework

Bei einer Ausnahme handelt es sich um einen Fehlerzustand oder unerwartetes Verhalten beim Ausführen eines Programms. Ausnahmen können durch Fehler in Ihrem oder aufgerufenem Code (z. B. bei freigegebenen Bibliotheken), nicht verfügbare Betriebssystemressourcen, unerwartete, von der CLR (Common Language Runtime) festgestellte Fehlerzustände (z. B. durch nicht überprüfbaren Code) und andere Ereignisse ausgelöst werden. Anwendungen können in einigen, aber nicht allen Fällen wiederhergestellt werden. Obwohl bei den meisten Anwendungsausnahmen eine Wiederherstellung möglich ist, ist dies beim Großteil der Laufzeitausnahmen nicht der Fall.

In .NET Framework stellt eine Ausnahme ein Objekt dar, das von der System.Exception-Klasse erbt. Eine Ausnahme wird in einem Codebereich ausgelöst, in dem ein Fehler aufgetreten ist. Die Ausnahme bleibt solange im Stapel, bis sie durch die Anwendung behandelt oder das Programm beendet wird.

Zurück nach oben

Ausnahmen im Vergleich zuherkömmlichen Fehlerbehandlungsmethoden

Herkömmliche Modelle der Fehlerbehandlung in Sprachen beruhten bisher entweder auf eigenen sprachenabhängigen Methoden der Fehlererkennung und -behandlung oder auf dem Fehlerbehandlungsmechanismus des Betriebsystems. Die CLR implementiert eine Ausnahmebehandlung mit folgenden Merkmalen:

  • Behandelt Ausnahmen ohne Berücksichtigung der Sprache, die die Ausnahme generiert oder behandelt.

  • Eine besondere Sprachsyntax ist für die Ausnahmebehandlung nicht erforderlich, trotzdem kann jede Sprache ihre eigene Syntax definieren.

  • Ausnahmen können prozess- und sogar computerübergreifend ausgelöst werden.

Ausnahmen bieten verschiedene Vorteile gegenüber anderen Methoden zur Fehlerbenachrichtigung, z. B. Rückgabecodes. Fehler können nicht unerkannt bleiben. Ungültige Werte werden im System nicht mehr weitergegeben. Sie müssen keine Rückgabecodes überprüfen. Der Ausnahmebehandlungscode kann leicht erweitert werden, um die Programmzuverlässigkeit zu erhöhen. Und schließlich ist die Ausnahmebehandlung der CLR schneller als die auf Windows basierende C++-Fehlerbehandlung.

Da Ausführungsthreads üblicherweise verwaltete und nicht verwaltete Codeblöcke abarbeiten, können Ausnahmen durch die CLR entweder in verwaltetem oder nicht verwaltetem Code ausgelöst und abgefangen werden. Nicht verwalteter Code kann sowohl SEH-Ausnahmen im C++-Format als auch COM-basierte HRESULTS enthalten.

Verwalten von Ausnahmen durch die Common Language Runtime

Die Common Language Runtime verwendet ein auf Ausnahmeobjekten und geschützten Codeblöcken basierendes Modell der Ausnahmebehandlung. Ein Exception-Objekt wird zur Darstellung einer auftretenden Ausnahme erstellt.

Durch die Common Language Runtime wird eine Tabelle mit Ausnahmeinformationen für jede ausführbare Datei erstellt. Jeder Methode einer ausführbaren Datei wird in dieser Tabelle ein (ggf. leeres) Array mit Informationen zur Ausnahmebehandlung zugeordnet. Jeder Eintrag in diesem Array beschreibt einen geschützten Codeblock, alle mit diesem Code verknüpften Ausnahmefilter und alle Ausnahmehandler (catch-Anweisungen). Die Ausnahmetabelle ist sehr effizient und führt nicht zu Leistungseinbußen bei der Prozessorzeit oder Speichernutzung, wenn eine Ausnahme nicht auftritt. Nur bei Auftreten einer Ausnahme werden Systemressourcen in Anspruch genommen.

Die Ausnahmetabelle enthält vier Typen von Ausnahmehandlern für geschützte Blöcke:

  • Der finally-Handler wird immer ausgeführt, wenn der Block durch die normale Ablaufsteuerung oder eine unbehandelte Ausnahme beendet wird.

  • Der fault-Handler wird immer beim Auftreten einer Ausnahme ausgeführt, aber nicht nach Abschluss der normalen Ablaufsteuerung.

  • Der typgefilterte Handler behandelt alle Ausnahmen einer angegebenen Klasse oder einer davon abgeleiteten Klasse.

  • Der benutzergefilterte Handler führt benutzerdefinierten Code aus, um zu entscheiden, ob die Ausnahme vom zugeordneten Handler behandelt oder dem nächsten geschützten Block übergeben wird.

Jede Sprache implementiert diese Ausnahmehandler entsprechend ihrer Spezifikationen. Zum Beispiel bietet Visual Basic Zugriff auf den benutzergefilterten Handler über einen Variablenvergleich in der catch-Anweisung (mit dem When-Schlüsselwort). In C# dagegen kann dieser Handler nicht implementiert werden.

Tritt eine Ausnahme auf, führt die Common Language Runtime die beiden folgenden Schritte durch:

  1. Die Common Language Runtime durchsucht das Array nach dem ersten geschützten Block, der folgende Eigenschaften besitzt:

    • Schützt einen Bereich, der die gerade ausgeführte Anweisung enthält.

    • einen Ausnahmehandler oder einen Filter zur Ausnahmebehandlung enthält.

  2. Im Fall einer Übereinstimmung wird von der Runtime ein Exception-Objekt erstellt, das die Ausnahme beschreibt. Daraufhin werden alle finally- oder fault-Anweisungen zwischen der Anweisung, bei der die Ausnahme auftrat, und derjenigen, die sie behandelt, ausgeführt. Die Reihenfolge der Ausnahmehandler ist wichtig: Der innerste Ausnahmehandler wird zuerst ausgewertet. Beachten Sie außerdem, dass Ausnahmehandler auf lokale Variablen und lokalen Arbeitsspeicher der Routine zugreifen können, durch die die Ausnahme abgefangen wurde, aber alle Zwischenwerte zum Zeitpunkt des Auslösens der Ausnahme verloren gehen.

    Enthält die aktuelle Methode keine Übereinstimmungen, durchsucht die Common Language Runtime jeden Aufrufer der aktuellen Methode und verfährt so weiter für den ganzen Stapel. Gibt es bei keinem Aufrufer eine Übereinstimmung, wird dem Debugger der Zugriff auf die Ausnahme gestattet. Wenn die Ausnahme durch den Debugger nicht behandelt wird, löst die CLR das AppDomain.UnhandledException-Ereignis aus. Sind keine Listener für dieses Ereignis vorhanden, gibt die Runtime eine Stapelüberwachung aus und beendet die Anwendung.

Zurück nach oben

Filtern von Laufzeitausnahmen

Sie können die abgefangenen Ausnahmen filtern und entweder nach Typ oder nach benutzerdefinierten Kriterien behandeln.

Typgefilterte Handler verwalten einen bestimmten Ausnahmetyp (oder davon abgeleitete Klassen). Das folgende Beispiel zeigt einen typgefilterten Handler, der für das Erfassen einer bestimmten Ausnahme konzipiert ist, in diesem Fall FileNotFoundException.

Catch e As FileNotFoundException
    Console.WriteLine("[Data File Missing] {0}", e)
catch (FileNotFoundException e)
{
    Console.WriteLine("[Data File Missing] {0}", e);
}
catch (FileNotFoundException^ e)
{
    Console::WriteLine("[Data File Missing] {0}", e);
}

Benutzergefilterte Handler fangen und behandeln Ausnahmen gemäß benutzerdefinierten Ausnahmebedingungen. Weitere Informationen über das Filtern von Ausnahmen mit dieser Methode finden Sie unter Verwenden spezifischer Ausnahmen in einem Catch-Block.

Zurück nach oben

Verwandte Themen

Titel

Beschreibung

Exception-Klasse und Exception-Eigenschaften

Beschreibt die Elemente eines Ausnahmeobjekts.

Ausnahmenhierarchie

Beschreibt die grundlegendsten Ausnahmen.

Grundlagen der Ausnahmebehandlung

Erläutert das Behandeln von Ausnahmen mit den Anweisungen catch, throw und finally.

Empfohlene Vorgehensweise für die Ausnahmebehandlung

Beschreibt empfohlene Methoden zur Ausnahmebehandlung.

Behandeln von COM-Interop-Ausnahmen

Erläutert die Behandlung von Ausnahmen, die in nicht verwaltetem Code ausgelöst und abgefangen wurden.

Gewusst wie: Zuordnen von HRESULTs und Ausnahmen

Erläutert die Zuordnung von Ausnahmen bei Übergängen zwischen verwaltetem und nicht verwaltetem Code.

Zurück nach oben

Verweis

System.Exception

System.ApplicationException

System.SystemException