Try...Catch...Finally-Anweisung (Visual Basic)
Bietet eine Möglichkeit, einige oder alle möglichen Fehler zu behandeln, die in einem bestimmten Codeblock auftreten können, während dieser Code noch ausgeführt wird.
Try
[ tryStatements ]
[ Exit Try ]
[ Catch [ exception [ As type ] ] [ When expression ]
[ catchStatements ]
[ Exit Try ] ]
[ Catch ... ]
[ Finally
[ finallyStatements ] ]
End Try
Bestandteile
Ausdruck |
Definition |
tryStatements |
Optional. Anweisungen, in denen ein Fehler auftreten kann. Hierbei kann es sich um eine zusammengesetzte Anweisung handeln. |
Catch |
Optional. Mehrere Catch-Blöcke sind zulässig. Wenn beim Verarbeiten des Try -Blocks eine Ausnahme auftritt, wird jede Catch-Anweisung in Textreihenfolge überprüft, um festzustellen, ob sie die Ausnahme behandelt, wobei exception die ausgelöste Ausnahme darstellt. |
exception |
Optional. Ein beliebiger Variablenname. Der Anfangswert von exception ist der Wert des ausgelösten Fehlers. Wird mit Catch zur Angabe des abgefangenen Fehlers verwendet. Wenn keine Angabe erfolgt, fängt die Catch-Anweisung alle Ausnahmen ab. |
type |
Optional. Gibt den Typ des Klassenfilters an. Wenn der Wert von exception dem von type angegebenen Typ oder einem abgeleiteten Typ entspricht, wird der Bezeichner an das Ausnahmeobjekt gebunden. |
When |
Optional. Eine Catch-Anweisung mit einer When-Klausel fängt nur Ausnahmen ab, wenn expression True ergibt. Eine When-Klausel wird nur angewendet, nachdem der Typ der Ausnahme überprüft wurde. expression kann auf den Bezeichner verweisen, der die Ausnahme darstellt. |
expression |
Optional. Muss implizit nach Boolean konvertierbar sein. Ein beliebiger Ausdruck, der einen allgemeinen Filter beschreibt. Dieses Argument wird meist zum Filtern nach Fehlernummern verwendet. Wird mit dem When-Schlüsselwort zur Angabe der Umstände, unter denen der Fehler abgefangen wurde, verwendet. |
catchStatements |
Optional. Anweisung(en) zur Behandlung von Fehlern, die im zugeordneten Try-Block auftreten. Hierbei kann es sich um eine zusammengesetzte Anweisung handeln. |
Exit Try |
Optional. Schlüsselwort zum Ausscheren aus der Try...Catch...Finally-Struktur. Die Ausführung wird mit dem Code fortgesetzt, der direkt auf die End Try-Anweisung folgt. Die Finally-Anweisung wird weiterhin ausgeführt. In Finally-Blöcken nicht zulässig. |
Finally |
Optional. Ein Finally-Block wird immer ausgeführt, wenn die Ausführung außerhalb eines beliebigen Teils der Try...Catch-Anweisung erfolgt. |
finallyStatements |
Optional. Anweisungen, die ausgeführt werden, nachdem die gesamte übrige Fehlerbehandlung erfolgt ist. |
End Try |
Beendet die Try...Catch...Finally-Struktur. |
Hinweise
Wenn Sie erwarten, dass eine bestimmte Ausnahme während der Ausführung eines bestimmten Codeabschnitts auftreten könnte, fügen Sie diesen Code in einen Try-Block ein, und verwenden Sie einen Catch-Block, um die Kontrolle zu behalten und die Ausnahme zu behandeln, falls sie auftritt.
Eine Try…Catch-Anweisung besteht aus einem Try-Block gefolgt von einer oder mehreren Catch-Klauseln, die Handler für verschiedene Ausnahmen angeben. Wenn in einem Try-Block eine Ausnahme ausgelöst wird, sucht Visual Basic nach der Catch-Anweisung, die die Ausnahme behandelt. Wenn eine entsprechende Catch-Anweisung nicht gefunden wird, untersucht Visual Basic die Methode, die die aktuelle Methode aufgerufen hat, und so weiter nach oben in der Aufrufliste. Wird kein Catch-Block gefunden, zeigt Visual Basic eine nicht bearbeitete Ausnahmemeldung für den Benutzer an und hält die Ausführung des Programms an.
Sie können mehr als eine Catch-Anweisung in einer Try…Catch-Anweisung verwenden. Wenn Sie dies tun, ist die Reihenfolge der Catch-Klauseln bedeutend, weil sie nacheinander überprüft werden. Präziser definierte Ausnahmen sollten vor weniger präzisen abgefangen werden.
Die folgenden Catch-Anweisungsbedingungen sind am unspezifischsten und fangen alle Ausnahmen, die von der Exception-Klasse abgeleitet sind, ab. Sie sollten üblicherweise eine dieser Variationen als letzten Catch-Block in der Try...Catch...Finally-Struktur verwenden, nachdem Sie alle spezifischen Ausnahmen abgefangen haben, die Sie erwarten. Die Ablaufsteuerung kann einen Catch-Block, auf der eine dieser Variationen folgt, niemals erreichen.
Der type lautet Exception, z. B.: Catch ex As Exception
Die Anweisung hat keine exception-Variable, Beispiel: Catch
Wenn eine Try…Catch…Finally-Anweisung in einem anderen Try-Block geschachtelt ist, untersucht Visual Basic zunächst jede Catch-Anweisung im innersten Try-Block. Wenn keine übereinstimmende Catch-Anweisung gefunden wird, wird die Suche in den Catch-Anweisungen äußeren Try…Catch…Finally-Blocks fortgeführt.
Lokale Variablen aus einem Try-Block sind in einem Catch-Block nicht verfügbar, weil es sich um eigene Blöcke handelt. Wenn Sie eine Variable in mehreren Blöcken verwenden möchten, deklarieren Sie die Variable außerhalb der Try...Catch...Finally-Struktur.
Tipp
Die Try…Catch…Finally-Anweisung ist als IntelliSense-Codeausschnitt verfügbar. Erweitern Sie im Codeausschnitt-Manager Codemuster - If, For Each, Try Catch, Property usw. und dann Fehlerbehandlung (Ausnahmen). Weitere Informationen finden Sie unter Gewusst wie: Einfügen von IntelliSense-Codeausschnitten.
Finally-Block
Wenn Sie über eine oder mehrere Anweisungen verfügen, die ausgeführt werden müssen, bevor die Try-Struktur beendet wird, verwenden Sie einen Finally-Block. Kurz vor Beendigung der Try…Catch-Struktur wird die Steuerung an den Finally-Block übergeben. Dies gilt auch, wenn in der Try-Struktur eine Ausnahme auftritt.
Ein Finally-Block ist nützlich zum Ausführen von Code, der ausgeführt werden muss, selbst wenn eine Ausnahme da ist. Die Steuerung wird an den Finally-Block übertragen, unabhängig davon, wie der Try...Catch-Block beendet wird.
Der Code in einem Finally-Block wird ausgeführt, selbst wenn Ihr Code einer Return-Anweisung in einem Try- oder Catch-Block begegnet. In den folgenden Fällen wird die Steuerung von einem Try-Block oder Catch-Block nicht an den entsprechenden Finally-Block übergeben:
Es befindet sich ein End-Anweisung innerhalb des Try-Blocks oder des Catch-Blocks.
Innerhalb des Try-Blocks oder Catch-Blocks wird eine StackOverflowException-Ausnahme ausgelöst.
Es ist nicht zulässig, die Ausführung explizit in einen Finally-Block zu übertragen. Außerdem ist die Übertragung der Ausführung aus einem Finally-Block nicht zulässig, außer durch eine Ausnahme.
Wenn die Try-Anweisung nicht mindestens einen Catch-enthält, muss sie einen Finally-Block enthalten.
Tipp
Sofern nicht bestimmte Ausnahmen abgefangen werden müssen, verhält sich die Using-Anweisung wie ein Try…Finally-Block und garantiert die Freigabe von Ressourcen unabhängig davon, wie die Ausführung des Blocks beendet wurde. Dies gilt auch bei einer unbehandelten Ausnahme. Weitere Informationen finden Sie unter Using-Anweisung (Visual Basic).
Ausnahmeargument
Das exception-Argument des Catch-Blocks ist eine Instanz der Exception-Klasse oder eine von der Exception-Klasse abgeleitete Klasse. Die Exception-Klasseninstanz entspricht dem im Try-Block aufgetretenen Fehler.
Die Eigenschaften des Objekts Exception helfen, die Ursache und den Ort einer Ausnahme zu bestimmen. Die StackTrace-Eigenschaft führt z. B. die aufgerufenen Methoden auf, die zur Ausnahme führten, und hilft Ihnen damit zu bestimmen, an welcher Stelle der Fehler im Code aufgetreten ist. Message gibt eine Meldung zurück, in der die Ausnahme beschrieben wird. HelpLink gibt einen Link auf eine zugehörige Hilfedatei zurück. InnerException gibt das Exception-Objekt zurück, das die aktuelle Ausnahme verursacht hat, oder es gibt Nothing zurück, wenn keine ursprüngliche Exception da ist.
Überlegungen beim Verwenden einer Try…Catch-Anweisung
Verwenden Sie eine Try…Catch-Anweisung nur, um das Eintreten ungewöhnlicher oder unerwarteter Programmereignisse zu signalisieren. Dies geschieht aus den folgenden Gründen:
Das Abfangen von Ausnahmen zur Laufzeit führt zu zusätzlichem Aufwand und ist wahrscheinlich langsamer als Vorabüberprüfungen, um Ausnahmen zu vermeiden.
Wenn ein Catch-Block nicht ordnungsgemäß behandelt wird, kann die Ausnahme für Benutzer möglicherweise nicht korrekt gemeldet werden.
Ausnahmebehandlung macht ein Programm komplexer.
Sie brauchen nicht immer eine Try…Catch Anweisung, um eine Bedingung zu überprüfen, die wahrscheinlich ist. Im folgenden Beispiel wird überprüft, ob eine Datei vorhanden ist, bevor versucht wird, sie zu öffnen. Dies reduziert die Notwendigkeit des Abfangens einer Ausnahme, die von der Methode OpenText ausgelöst wird.
Private Sub TextFileExample(ByVal filePath As String)
' Verify that the file exists.
If System.IO.File.Exists(filePath) = False Then
Console.Write("File Not Found: " & filePath)
Else
' Open the text file and display its contents.
Dim sr As System.IO.StreamReader =
System.IO.File.OpenText(filePath)
Console.Write(sr.ReadToEnd)
sr.Close()
End If
End Sub
Stellen Sie sicher, dass Code in Catch-Blöcken ordnungsgemäß Ausnahmen für Benutzer melden können, sei es durch threadsichere Protokollierung oder entsprechende Meldungen. Andernfalls bleiben Ausnahmen möglicherweise unbekannt.
Teilweise vertrauenswürdige Situationen
In teilweise vertrauenswürdigen Kontexten, z. B. in einer Anwendung, die auf einer Netzwerkfreigabe bereitgestellt wird, fängt Try...Catch...Finally keine Sicherheitsausnahmen ab, die vor dem Aufrufen der den Aufruf enthaltenden Methode auftreten. Wenn der Code im folgenden Beispiel auf einer Serverfreigabe bereitgestellt und von dort ausgeführt wird, wird der Fehler "System.Security.SecurityException: Fehler bei der Anforderung" ausgelöst. Weitere Informationen über Sicherheitsausnahmen finden Sie in der SecurityException-Klasse.
Try
Process.Start("https://www.microsoft.com")
Catch ex As Exception
MsgBox("Can't load Web page" & vbCrLf & ex.Message)
End Try
In einem solchen teilweise vertrauenswürdigen Kontext müssen Sie die Process.Start-Anweisung in eine eigene Sub einfügen. Der ursprüngliche Aufruf von Sub schlägt fehl. Dies ermöglicht Try...Catch die Ausnahme abzufangen, bevor die Sub, die Process.Start enthält, gestartet und die Sicherheitsausnahme ausgelöst wird.
Beispiel
Das folgende Beispiel veranschaulicht die Struktur für die Try...Catch...Finally-Anweisung.
Public Sub TryExample()
' Declare variables.
Dim x As Integer = 5
Dim y As Integer = 0
' Set up structured error handling.
Try
' Cause a "Divide by Zero" exception.
x = x \ y
' This statement does not execute because program
' control passes to the Catch block when the
' exception occurs.
MessageBox.Show("end of Try block")
Catch ex As Exception
' Show the exception's message.
MessageBox.Show(ex.Message)
' Show the stack trace, which is a list of methods
' that are currently executing.
MessageBox.Show("Stack Trace: " & vbCrLf & ex.StackTrace)
Finally
' This line executes whether or not the exception occurs.
MessageBox.Show("in Finally block")
End Try
End Sub
Im folgenden Beispiel löst die CreateException-Methode eine NullReferenceException aus. Der Code, der die Ausnahme generiert, ist nicht in einem Try-Block. Daher behandelt die CreateException-Methode die Ausnahme nicht. Die RunSample-Methode behandeln die Ausnahme, da sich der Aufruf der Methode CreateException in einem Try-Block befindet.
Das Beispiel enthält die Catch-Anweisungen für verschiedene Arten von Ausnahmen, geordnet von der speziellsten zur allgemeinsten.
Public Sub RunSample()
Try
CreateException()
Catch ex As System.IO.IOException
' Code that reacts to IOException.
Catch ex As NullReferenceException
MessageBox.Show("NullReferenceException: " & ex.Message)
MessageBox.Show("Stack Trace: " & vbCrLf & ex.StackTrace)
Catch ex As Exception
' Code that reacts to any other exception.
End Try
End Sub
Private Sub CreateException()
' This code throws a NullReferenceException.
Dim obj = Nothing
Dim prop = obj.Name
' This code also throws a NullReferenceException.
'Throw New NullReferenceException("Something happened.")
End Sub
Im folgenden Beispiel wird veranschaulicht, wie eine Catch When-Anweisung verwendet wird, um einen bedingten Ausdruck zu filtern. Wenn der bedingte Ausdruck zu True ausgewertet wird, wird der Code im Block Catch ausgeführt.
Private Sub WhenExample()
Dim i As Integer = 5
Try
Throw New ArgumentException()
Catch e As OverflowException When i = 5
Console.WriteLine("First handler")
Catch e As ArgumentException When i = 4
Console.WriteLine("Second handler")
Catch When i = 5
Console.WriteLine("Third handler")
End Try
End Sub
' Output: Third handler
Im folgenden Beispiel ist eine Try…Catch -Anweisung, die in einem Try-Block enthalten ist. Der innere Catch-Block löst eine Ausnahme aus, bei der die InnerException-Eigenschaft auf die ursprüngliche Ausnahme festgelegt ist. Der äußere Catch-Block meldet seine eigene Ausnahme und die innere Ausnahme.
Private Sub InnerExceptionExample()
Try
Try
' Set a reference to a StringBuilder.
' The exception below does not occur if the commented
' statement is used instead.
Dim sb As System.Text.StringBuilder
'Dim sb As New System.Text.StringBuilder
' Cause a NullReferenceException.
sb.Append("text")
Catch ex As Exception
' Throw a new exception that has the inner exception
' set to the original exception.
Throw New ApplicationException("Something happened :(", ex)
End Try
Catch ex2 As Exception
' Show the exception.
Console.WriteLine("Exception: " & ex2.Message)
Console.WriteLine(ex2.StackTrace)
' Show the inner exception, if one is present.
If ex2.InnerException IsNot Nothing Then
Console.WriteLine("Inner Exception: " & ex2.InnerException.Message)
Console.WriteLine(ex2.StackTrace)
End If
End Try
End Sub
Siehe auch
Referenz
On Error-Anweisung (Visual Basic)
Throw-Anweisung (Visual Basic)
Konzepte
Empfohlene Vorgehensweise für die Verwendung von IntelliSense-Codeausschnitten
Ausnahmebehandlung (Task Parallel Library)
Weitere Ressourcen
Strukturierte Ausnahmebehandlung in Visual Basic
Änderungsprotokoll
Datum |
Versionsgeschichte |
Grund |
April 2011 |
Neu organisiert und Hinweise ergänzt sowie Beispiele hinzugefügt. |
Informationsergänzung. |