Untersuchen von Ausnahmen und des Ausnahmebehandlungsprozesses
- 11 Minuten
Laufzeitfehler in einer C#-Anwendung werden mithilfe eines Mechanismus verwaltet, der als Ausnahmen bezeichnet wird. Ausnahmen bieten eine strukturierte, einheitliche und typsichere Methode zur Behandlung von Fehlerbedingungen auf Systemebene und Anwendungsebene. Ausnahmen werden von der .NET-Laufzeit oder vom Code in einer Anwendung generiert.
Häufige Szenarien, für die eine Ausnahmebehandlung erforderlich ist
Es gibt mehrere Programmierszenarien, die eine Ausnahmebehandlung erfordern. Viele dieser Szenarien umfassen eine Form der Datenerfassung. Obwohl einige Szenarien Codierungstechniken umfassen, die sich außerhalb des Umfangs dieser Schulung befinden, sind sie dennoch erwähnenswert.
Häufige Szenarien, für die eine Ausnahmebehandlung erforderlich ist, umfassen:
Benutzereingabe: Ausnahmen können auftreten, wenn Code die Benutzereingabe verarbeitet. Beispielsweise treten Ausnahmen auf, wenn der Eingabewert im falschen Format oder außerhalb des Bereichs liegt.
Datenverarbeitung und Berechnung: Ausnahmen können auftreten, wenn Code Datenberechnungen oder Konvertierungen durchführt. Beispielsweise treten Ausnahmen auf, wenn im Code versucht wird, durch null zu dividieren, in einen nicht unterstützten Typ umzuwandeln oder einen Wert außerhalb des zulässigen Bereichs zuzuweisen.
Dateieingabe-/Ausgabevorgänge: Ausnahmen können auftreten, wenn Code aus einer Datei liest oder in eine Datei schreibt. Beispielsweise treten Ausnahmen auf, wenn die Datei nicht vorhanden ist, das Programm nicht über die Berechtigung für den Zugriff auf die Datei verfügt oder die Datei von einem anderen Prozess verwendet wird.
Datenbankvorgänge: Ausnahmen können auftreten, wenn Code mit einer Datenbank interagiert. Beispielsweise treten Ausnahmen auf, wenn die Datenbankverbindung verloren geht, in einer SQL-Anweisung ein Syntaxfehler auftritt oder eine Einschränkungsverletzung auftritt.
Netzwerkkommunikation: Ausnahmen können auftreten, wenn Code über ein Netzwerk kommuniziert. Beispielsweise treten Ausnahmen auf, wenn die Netzwerkverbindung verloren geht, ein Timeout auftritt oder der Remoteserver einen Fehler zurückgibt.
Andere externe Ressourcen: Ausnahmen können auftreten, wenn Code mit anderen externen Ressourcen kommuniziert. Webdienste, REST-APIs oder Bibliotheken von Drittanbietern können Ausnahmen aus verschiedenen Gründen auslösen. Beispielsweise treten Ausnahmen aufgrund von Netzwerkverbindungen, fehlerhaften Daten usw. auf.
Schlüsselwörter, Codeblöcke und Muster für die Ausnahmebehandlung
Die Ausnahmebehandlung in C# wird durch die Schlüsselwörter try, catch und finally implementiert. Jedes dieser Schlüsselwörter verfügt über einen zugeordneten Codeblock und kann verwendet werden, um ein bestimmtes Ziel in Ihrem Ansatz für die Ausnahmebehandlung zu erfüllen. Beispiel:
try
{
// try code block - code that may generate an exception
}
catch
{
// catch code block - code to handle an exception
}
finally
{
// finally code block - code to clean up resources
}
Hinweis
Die C#-Sprache ermöglicht ihrem Code auch das Generieren eines Ausnahmeobjekts mithilfe des throw Schlüsselworts. Ausnahmebehandlungsszenarien, die die Verwendung des throw Schlüsselworts zum Generieren von Ausnahmen umfassen, werden in einem separaten Modul in Microsoft Learn behandelt.
Der try-Codeblock enthält den überwachten Code, der möglicherweise eine Ausnahme verursacht. Wenn der Code innerhalb eines try Blocks eine Ausnahme verursacht, wird die Ausnahme von einem entsprechenden catch Block behandelt.
Der catch-Codeblock enthält den Code, der bei Auftreten einer Ausnahme ausgeführt wird. Der catch Block kann die Ausnahme behandeln, sie protokollieren oder ignorieren. Ein catch Block kann so konfiguriert werden, dass er ausgeführt wird, wenn ein Ausnahmetyp auftritt, oder nur, wenn ein bestimmter Ausnahmetyp auftritt.
Der finally Codeblock enthält Code, der ausführt, ob eine Ausnahme auftritt oder nicht. Der finally Block wird häufig verwendet, um alle Ressourcen zu bereinigen, die in einem try Block zugeordnet sind. Stellen Sie sicher, dass einer Variablen beispielsweise der richtige oder erforderliche Wert zugewiesen wird.
Die Ausnahmebehandlung in einer C#-Anwendung wird in der Regel mithilfe eines oder mehrerer der folgenden Muster implementiert:
- Das
try-catchMuster besteht aus einemtryBlock gefolgt von einer odercatchmehreren Klauseln. JedercatchBlock wird verwendet, um Handler für unterschiedliche Ausnahmen anzugeben. - Das
try-finallyMuster besteht aus einemtryBlock gefolgt von einemfinallyBlock. In der Regel werden die Anweisungen einesfinallyBlocks ausgeführt, wenn das Steuerelement einetryAnweisung verlässt. - Das
try-catch-finallyMuster implementiert alle drei Arten von Ausnahmebehandlungsblöcken. Ein häufiges Szenario für dastry-catch-finallyMuster ist, wenn Ressourcen in einemtryBlock abgerufen und verwendet werden, außergewöhnliche Umstände in einemcatchBlock verwaltet werden und die Ressourcen freigegeben oder anderweitig imfinallyBlock verwaltet werden.
Wie werden Ausnahmen im Code dargestellt?
Ausnahmen werden im Code als Objekte dargestellt, was bedeutet, dass sie eine Instanz einer Klasse sind. Die .NET-Klassenbibliothek bietet Ausnahmeklassen, auf die im Code zugegriffen wird, genau wie andere .NET-Klassen. Ein weiteres Beispiel für .NET-Klasse, die als Objekt im Code verwendet wird, ist die Random Klasse (die zum Erstellen von Zufallszahlen verwendet wird).
Genauer gesagt sind Ausnahmen Typen, die durch Klassen dargestellt werden, welche letztendlich von System.Exception abgeleitet sind. Eine von dieser abgeleitete Exception Ausnahmeklasse enthält Informationen, die den Ausnahmetyp identifizieren und Eigenschaften enthalten, die Details zur Ausnahme bereitstellen. Eine detailliertere Untersuchung der Exception Klasse ist später in diesem Modul enthalten.
Eine Laufzeitinstanz einer Klasse wird in der Regel als Objekt bezeichnet, sodass Ausnahmen häufig als Ausnahmeobjekte bezeichnet werden.
Hinweis
Obwohl sie manchmal austauschbar verwendet werden, sind eine Klasse und ein Objekt verschiedene Dinge. Eine Klasse definiert einen Objekttyp, aber es handelt sich nicht um ein Objekt selbst. Ein Objekt ist eine konkrete Entität, die auf einer Klasse basiert.
Ausnahmebehandlungsprozess
Wenn eine Ausnahme auftritt, sucht die .NET-Laufzeit nach der nächstgelegenen catch Klausel, die die Ausnahme behandeln kann. Der Prozess beginnt mit der Methode, die dazu führte, dass die Ausnahme ausgelöst wurde. Zunächst wird die Methode untersucht, um festzustellen, ob sich der Code, der die Ausnahme verursacht hat, in einem try Codeblock befindet. Wenn sich der Code innerhalb des try Codeblocks befindet, werden die catch Klauseln, die der try Anweisung zugeordnet sind, in der vorgeschriebenen Reihenfolge berücksichtigt. Wenn die catch Klauseln die Ausnahme nicht verarbeiten können, wird die Methode, die die aktuelle Methode aufgerufen hat, durchsucht. Diese Methode wird untersucht, um festzustellen, ob sich der Methodenaufruf (an die erste Methode) in einem try Codeblock befindet. Wenn sich der Aufruf in einem try Codeblock befindet, werden die zugehörigen catch Klauseln berücksichtigt. Dieser Suchvorgang wird fortgesetzt, bis eine catch Klausel gefunden wird, die die aktuelle Ausnahme behandeln kann.
Sobald eine catch Klausel gefunden wurde, die die Ausnahme verarbeiten kann, bereitet die Laufzeit die Übertragung der Steuerung auf die erste Anweisung des catch Blocks vor. Bevor die Ausführung des catch Blocks beginnt, führt die Laufzeit jedoch alle finally Blöcke aus, die mit try Anweisungen verknüpft sind, die während der Suche gefunden wurden. Wenn mehr als ein finally Block gefunden wird, werden sie in der Reihenfolge ausgeführt, beginnend mit dem Code, der dem Code am nächsten kommt, der die Ausnahme ausgelöst hat.
Wenn keine catch Klausel für die Behandlung der Ausnahme gefunden wird, beendet die Laufzeit die Anwendung und zeigt dem Benutzer eine Fehlermeldung an.
Betrachten Sie das folgende Codebeispiel, das ein try-finally muster enthält, das in einem try-catch Muster geschachtelt ist:
try
{
// Step 1: code execution begins
try
{
// Step 2: an exception occurs here
}
finally
{
// Step 4: the system executes the finally code block associated with the try statement where the exception occurred
}
}
catch // Step 3: the system finds a catch clause that can handle the exception
{
// Step 5: the system transfers control to the first line of the catch code block
}
In diesem Beispiel tritt der folgende Prozess auf:
- Die Ausführung beginnt im Codeblock der äußeren
tryAnweisung. - Im Codeblock der inneren
try-Anweisung wird eine Ausnahme ausgelöst. - Die Runtime findet die
catch-Klausel, die der äußerentry-Anweisung zugeordnet ist. - Bevor die Laufzeit die Steuerung an die erste Zeile des
catchCodeblocks überträgt, wird diefinallyklausel ausgeführt, die der innerentryAnweisung zugeordnet ist. - Die Laufzeit überträgt dann die Steuerung an die erste Zeile des
catchCodeblocks und führt den Code aus, der die Ausnahme behandelt.
In diesem einfachen Beispiel befinden sich die geschachtelten try-catch und try-finally Muster in einer einzigen Methode, aber mehrere try-catch und try-finally Muster können zwischen Methoden verteilt werden, die andere Methoden aufrufen.
Ausnahmebehandlung und Aufrufliste
Der Begriff „Aufruflistenentladung“ wird Ihnen häufig begegnen, wenn Sie sich über die Ausnahmebehandlung und den Ausnahmebehandlungsprozess informieren. Um diesen Begriff zu verstehen, müssen Sie den Aufrufstapel verstehen und wie er verwendet wird, um den "Stapel" von Methodenaufrufen während der Codeausführung nachzuverfolgen.
Sie können sich die Aufrufliste wie einen Turm aus Bauklötzen vorstellen. Wenn Sie einen Turm bauen, beginnen Sie mit nur einem Block. Jedes Mal, wenn Sie dem Turm einen Block hinzufügen, platzieren Sie ihn auf den vorhandenen Blöcken. Wenn Ihre Anwendung im Debugger läuft, ist der Einstiegspunkt zu Ihrer Anwendung die erste Ebene, die dem Aufrufstapel (der erste Block im Turm) hinzugefügt wird. Jedes Mal, wenn eine Methode eine andere Methode aufruft, wird die neue Methode oben im Stapel hinzugefügt. Wenn Ihr Code eine Methode verlässt, wird die Methode aus dem Aufrufstapel entfernt.
Hinweis
Bei einer Konsolenanwendung ist der Einstiegspunkt zu Ihrer Anwendung die Anweisungen der obersten Ebene. Im Visual Studio Code-Aufrufstapel wird dieser Einstiegspunkt als Main Methode bezeichnet.
Die Aufruflistenentladung ist der Prozess, der von der .NET-Runtime eingesetzt wird, wenn bei einem C#-Programm ein Fehler auftritt. Es ist derselbe Prozess, den Sie gerade überprüft haben.
Kehren Sie zurück zur Blockturm-Analogie: Wenn Sie einen Block vom Turm entfernen müssen, beginnen Sie von oben und entfernen jeden Block, bis Sie den benötigten Block erreichen. Dieser Prozess ähnelt der Funktionsweise des Entwirrens von Aufrufstapeln, wobei jede Schicht im Aufrufstapel wie ein Block im Turm ist. Wenn die Runtime den Aufrufstapel entladen muss, beginnt sie von oben und entfernt die einzelnen Aufrufebenen, bis sie die gewünschte erreicht. In diesem Fall handelt es sich bei der benötigten Aufrufebene um die Methode mit einer catch Klausel, die die aufgetretene Ausnahme verarbeiten kann.
Zusammenfassung
Nachstehend finden Sie nochmals die wichtigsten Punkte aus dieser Lerneinheit:
- Häufige Szenarien, die eine Ausnahmebehandlung erfordern können, umfassen Benutzereingaben, Datenverarbeitung, Datei-E/A-Vorgänge, Datenbankvorgänge und Netzwerkkommunikation.
- Die Ausnahmebehandlung in C# wird mithilfe von
try,catchundfinallySchlüsselwörtern implementiert. Jedes Schlüsselwort verfügt über einen zugeordneten Codeblock, der einem bestimmten Zweck dient. - Ausnahmen werden als Typen dargestellt und von der
System.ExceptionKlasse in .NET abgeleitet. Ausnahmen enthalten Informationen, mit denen der Ausnahmetyp identifiziert wird, und Eigenschaften, die zusätzliche Details bereitstellen. - Wenn eine Ausnahme auftritt, sucht die .NET-Laufzeit nach der nächstgelegenen
catchKlausel, die sie behandeln kann. Die Suche beginnt mit der Methode, bei der die Ausnahme ausgelöst wurde, und verschiebt den Aufrufstapel bei Bedarf nach unten.