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 weiterhin Code ausgeführt wird.

Syntax

Try
    [ tryStatements ]
    [ Exit Try ]
[ Catch [ exception [ As type ] ] [ When expression ]
    [ catchStatements ]
    [ Exit Try ] ]
[ Catch ... ]
[ Finally
    [ finallyStatements ] ]
End Try

Bestandteile

Begriff Definition
tryStatements Dies ist optional. Anweisungen, bei denen ein Fehler auftreten kann. Kann eine Verbundanweisung sein.
Catch Optional. Mehrere Catch Blöcke sind zulässig. Wenn bei der Verarbeitung des -Blocks eine Ausnahme auftritt, wird jede Anweisung in textlicher Reihenfolge untersucht, um zu bestimmen, ob sie die Ausnahme behandelt, und die ausgelöste Try Catch Ausnahme exception darstellt.
exception Optional. Ein beliebiger Variablenname. Der Anfangswert von exception ist der Wert des ausgelösten Fehlers. Wird mit Catch verwendet, um den erfassten Fehler anzugeben. Wenn diese Angabe nicht angegeben wird, Catch fängt die Anweisung alle Ausnahmen ab.
type Optional. Gibt den Typ des Klassenfilters an. Wenn der Wert von vom typ ist, der durch oder von einem abgeleiteten Typ angegeben wird, wird der Bezeichner exception type an das Ausnahmeobjekt gebunden.
When Optional. Eine Catch -Anweisung mit einer When -Klausel fängt Ausnahmen nur ab, expression wenn als ausgewertet True wird. Eine -Klausel wird erst angewendet, nachdem der Typ der Ausnahme überprüft wurde, und kann When auf den Bezeichner verweisen, expression der die Ausnahme darstellt.
expression Optional. Muss implizit in konvertierbar Boolean sein. Jeder Ausdruck, der einen generischen Filter beschreibt. Wird normalerweise verwendet, um nach Fehlernummer zu filtern. Wird mit dem When Schlüsselwort verwendet, um Die Umstände anzugeben, unter denen der Fehler erfasst wird.
catchStatements Optional. Anweisungen zum Behandeln von Fehlern, die im zugeordneten Block Try auftreten. Kann eine Verbundanweisung sein.
Exit Try Optional. Schlüsselwort, das aus der -Struktur Try...Catch...Finally herausbricht. Die Ausführung wird mit dem Code unmittelbar nach der -Anweisung End Try fortgesetzt. Die Finally -Anweisung wird weiterhin ausgeführt. In -Blöcken Finally nicht zulässig.
Finally Optional. Ein Finally Block wird immer ausgeführt, wenn die Ausführung einen beliebigen Teil der Anweisung Try...Catch verlässt.
finallyStatements Optional. Anweisungen, die ausgeführt werden, nachdem alle anderen Fehlerverarbeitungen aufgetreten sind.
End Try Beendet die Try...Catch...Finally -Struktur.

Bemerkungen

Wenn Sie davon ausgehen, dass eine bestimmte Ausnahme während eines bestimmten Codeabschnitts auftreten kann, legen Sie den Code in einen -Block ein, und verwenden Sie einen -Block, um die Kontrolle zu behalten und die Ausnahme zu behandeln, wenn sie Try Catch auftritt.

Eine Try…Catch -Anweisung besteht aus einem -Block, gefolgt von einer oder mehreren -Klauseln, die Try Handler für verschiedene Ausnahmen Catch angeben. Wenn eine Ausnahme in einem -Block ausgelöst wird, Visual Basic nach der Try Catch Anweisung, die die Ausnahme behandelt. Wenn keine übereinstimmende Anweisung gefunden wird, Visual Basic die Methode, die die aktuelle Methode aufgerufen hat, und so weiter oben in Catch der Aufrufliste. Wenn kein Block gefunden wird, Visual Basic eine nicht behandelte Ausnahmemeldung für den Benutzer angezeigt und Catch die Ausführung des Programms beendet.

Sie können mehrere Anweisungen Catch in einer -Anweisung Try…Catch verwenden. Wenn Sie dies tun, ist die Reihenfolge der Catch Klauseln von Bedeutung, da sie in der angegebenen Reihenfolge untersucht werden. Fangen Sie spezifischere Ausnahmen vor den weniger spezifischen ab.

Die folgenden Anweisungsbedingungen sind am wenigsten spezifisch und fangen alle Ausnahmen Catch ab, die von der -Klasse Exception ableiten. Normalerweise sollten Sie eine dieser Variationen als letzten Block in der Struktur verwenden, nachdem Sie alle spezifischen Ausnahmen, die Catch Try...Catch...Finally Sie erwarten, abfangen haben. Die Ablaufsteuerung kann niemals einen Block Catch erreichen, der einer dieser Variationen folgt.

  • Der type ist Exception , z. B.: Catch ex As Exception

  • Die Anweisung verfügt über exception keine Variable, z. B.: Catch

Wenn eine Anweisung in einem anderen Block geschachtelt ist, Visual Basic zuerst jede Anweisung Try…Catch…Finally Try im Catch innersten Block Try untersucht. Wenn keine Catch übereinstimmende Anweisung gefunden wird, wird die Suche mit den Catch Anweisungen des äußeren Blocks Try…Catch…Finally fortgesetzt.

Lokale Variablen aus einem Try -Block sind in einem -Block nicht Catch verfügbar, da es sich um separate Blöcke handelt. Wenn Sie eine Variable in mehr als einem Block 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 Codeausschnitte.

Finally-Block

Wenn Sie über eine oder mehrere Anweisungen verfügen, die ausgeführt werden müssen, bevor Sie die Struktur Try beenden, verwenden Sie einen Finally -Block. Die Steuerung wird an den Finally -Block direkt vor der Ausgliederung der -Struktur Try…Catch übergibt. Dies gilt auch, wenn eine Ausnahme an einer beliebigen Stelle innerhalb der -Struktur Try auftritt.

Ein Finally -Block ist nützlich für die Ausführung von Code, der auch dann ausgeführt werden muss, wenn eine Ausnahme vor liegt. Die Steuerung wird unabhängig davon, wie der Block Finally Try...Catch beendet wird, an den -Block übergeben.

Der Code in einem Finally -Block wird auch dann ausgeführt, wenn ihr Code auf eine Return -Anweisung in einem - oder Try -Block Catch trifft. Die Steuerung wird in den folgenden Fällen nicht von einem - oder -Block an den Try Catch entsprechenden Finally -Block übergeben:

Es ist nicht zulässig, die Ausführung explizit in einen -Block zu Finally übertragen. Das Übertragen der Ausführung aus Finally einem Block ist ungültig, außer durch eine Ausnahme.

Wenn eine Try Anweisung nicht mindestens einen Block Catch enthält, muss sie einen -Block Finally enthalten.

Tipp

Wenn Sie bestimmte Ausnahmen nicht abfangen müssen, verhält sich die Anweisung wie ein -Block und garantiert die Beseitigung der Ressourcen, unabhängig davon, wie Sie Using Try…Finally den Block beenden. Dies gilt auch bei einer nicht behandelten Ausnahme. Weitere Informationen finden Sie unter using-Anweisung.

Ausnahmeargument

Das Catch exception Blockargument ist eine Instanz der Exception -Klasse oder eine Klasse, die von der -Klasse Exception ableitung. Die Exception Klasseninstanz entspricht dem Fehler, der im -Block aufgetreten Try ist.

Die Eigenschaften des Exception -Objekts helfen, die Ursache und den Speicherort einer Ausnahme zu identifizieren. Die -Eigenschaft listet beispielsweise die aufgerufenen Methoden auf, die zu der Ausnahme geführt haben, damit Sie feststellen können, wo StackTrace der Fehler im Code aufgetreten ist. Message gibt eine Meldung zurück, die die Ausnahme beschreibt. HelpLink gibt einen Link zu einer zugeordneten Hilfedatei zurück. InnerExceptiongibt das Objekt zurück, das die aktuelle Ausnahme verursacht hat, oder gibt Exception zurück, Nothing wenn kein ursprüngliches -Objekt vorkommt. Exception

Überlegungen bei der Verwendung eines Try... Catch-Anweisung

Verwenden Sie Try…Catch eine -Anweisung nur, um das Auftreten ungewöhnlicher oder unerwarteter Programmereignisse zu signalisieren. Dies kann folgende Gründe haben:

  • Das Abfangen von Ausnahmen zur Laufzeit führt zu zusätzlichem Mehraufwand und ist wahrscheinlich langsamer als die Vorabüberprüfung, um Ausnahmen zu vermeiden.

  • Wenn ein Catch Block nicht ordnungsgemäß behandelt wird, wird die Ausnahme möglicherweise nicht ordnungsgemäß an Benutzer gemeldet.

  • Durch die Ausnahmebehandlung wird ein Programm komplexer.

Sie benötigen nicht immer eine -Anweisung, um eine Bedingung zu Try…Catch überprüfen, die wahrscheinlich auftritt. Im folgenden Beispiel wird überprüft, ob eine Datei vorhanden ist, bevor versucht wird, sie zu öffnen. Dies reduziert die Notwendigkeit, eine von der -Methode ausgelöste Ausnahme OpenText abfangen zu müssen.

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 Blöcken Ausnahmen ordnungsgemäß an Benutzer melden kann, sei es durch Catch threadsichere Protokollierung oder entsprechende Meldungen. Andernfalls bleiben Ausnahmen möglicherweise unbekannt.

Asynchrone Methoden

Wenn Sie eine Methode mit dem Modifizierer Async markieren, können Sie den Await-Operator in der -Methode verwenden. Eine -Anweisung mit dem Await -Operator unterbricht die Ausführung der -Methode, bis die erwartete Aufgabe abgeschlossen ist. Die Aufgabe stellt derzeit ausgeführte Arbeit dar. Wenn die Aufgabe, die dem Operator zugeordnet Await ist, abgeschlossen ist, wird die Ausführung in derselben Methode fortgesetzt. Weitere Informationen finden Sie unter Steuern Flow in asynchronen Programmen.

Eine aufgabe, die von einer Async-Methode zurückgegeben wird, endet möglicherweise in einem fehlerhaften Zustand und gibt an, dass sie aufgrund einer nicht behandelten Ausnahme abgeschlossen wurde. Eine Aufgabe kann auch in einem abgebrochenen Zustand enden, was dazu führt, dass eine OperationCanceledException aus dem await-Ausdruck ausgelöst wird. Um beide Ausnahmetypen abzufangen, platzieren Sie den Await Ausdruck, der der Aufgabe zugeordnet ist, in einem Try -Block, und fangen Sie die Ausnahme im Catch -Block ab. Ein Beispiel finden Sie weiter unten in diesem Thema.

Ein Task kann sich in einem Fehlerhaften Zustand befinden, da mehrere Ausnahmen für den Fehler verantwortlich waren. Beispielsweise kann die Aufgabe das Ergebnis eines Aufrufs an Task.WhenAll sein. Wenn Sie auf eine solche Aufgabe warten, ist die abgefangene Ausnahme nur eine der Ausnahmen, und Sie können nicht vorhersagen, welche Ausnahme abgefangen wird. Ein Beispiel finden Sie weiter unten in diesem Thema.

Ein Await Ausdruck darf sich nicht innerhalb eines Blocks oder Blocks Catch Finally befinden.

Iterators

Eine Iteratorfunktion oder Get ein Accessor führt eine benutzerdefinierte Iteration über eine Auflistung aus. Ein Iterator verwendet eine Yield-Anweisung, um jedes Element der Auflistung einzeln zurückzugeben. Sie rufen eine Iteratorfunktion auf, indem Sie for Each... Nächste Anweisung.

Eine Yield -Anweisung kann sich in einem Try -Block befinden. Ein Try -Block, der eine Yield -Anweisung enthält, kann Catch Blöcke und einen Finally -Block enthalten. Ein Beispiel finden Sie im Abschnitt "Try Blocks in Visual Basic" (Ausprobieren von Blöcken in Visual Basic) von Iteratoren.

Eine Yield -Anweisung darf sich nicht in einem Catch -Block oder Finally -Block befinden.

Wenn der For Each Text (außerhalb der Iteratorfunktion) eine Ausnahme auslöst, wird ein Catch Block in der Iteratorfunktion nicht ausgeführt, aber ein Finally Block in der Iteratorfunktion wird ausgeführt. Ein Catch Block innerhalb einer Iteratorfunktion fängt nur Ausnahmen ab, die innerhalb der Iteratorfunktion auftreten.

Situationen mit teilweiser Vertrauenswürdigkeit

In Situationen mit teilweiser Vertrauenswürdigkeit, z. B. einer anwendung, die auf einer Netzwerkfreigabe gehostet wird, werden keine Try...Catch...Finally Sicherheitsausnahmen erfasst, die auftreten, bevor die Methode aufgerufen wird, die den Aufruf enthält. Wenn Sie sie im folgenden Beispiel auf einer Serverfreigabe speichern und von dort aus ausführen, wird der Fehler "System.Security.SecurityException: Anforderung fehlgeschlagen" ausgegeben. Weitere Informationen zu Sicherheits ausnahmen finden Sie in der SecurityException -Klasse.

Try
    Process.Start("http://www.microsoft.com")
Catch ex As Exception
    MsgBox("Can't load Web page" & vbCrLf & ex.Message)
End Try

In einer solchen teilweise vertrauenswürdigen Situation müssen Sie die Process.Start -Anweisung in eine separate Sub setzen. Beim ersten Aufruf von Sub tritt ein Fehler auf. Dadurch kann es vor dem Starten des mit und Try...Catch Sub der Process.Start erzeugten Sicherheitsausnahme abfangen.

Beispiele

Die Struktur von Try... Fangen... Schließlich

Im folgenden Beispiel wird die Struktur der Try...Catch...Finally -Anweisung veranschaulicht.

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

Ausnahme in einer Methode, die aus einem Try-Block aufgerufen wird

Im folgenden Beispiel löst die CreateException -Methode eine NullReferenceException aus. Der Code, der die Ausnahme generiert, befindet sich nicht in einem Try -Block. Daher behandelt die CreateException -Methode die Ausnahme nicht. Die RunSample -Methode behandelt die Ausnahme, da sich der Aufruf der CreateException -Methode in einem Try -Block befindet.

Das Beispiel enthält Catch Anweisungen für verschiedene Arten von Ausnahmen, sortiert von der spezifischsten bis 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

Die Catch When-Anweisung

Das folgende Beispiel zeigt, wie sie eine Catch When -Anweisung verwenden, um nach einem bedingten Ausdruck zu filtern. Wenn der bedingte Ausdruck True ergibt, wird der Code im Catch -Block 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

Geschachtelte Try-Anweisungen

Das folgende Beispiel enthält eine Try…Catch -Anweisung, die in einem -Block enthalten Try ist. Der innere Catch Block löst eine Ausnahme aus, deren 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
            ' out 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

Ausnahmebehandlung für asynchrone Methoden

Im folgenden Beispiel wird die Ausnahmebehandlung für asynchrone Methoden veranschaulicht. Um eine Ausnahme abzufangen, die für eine asynchrone Aufgabe gilt, befindet sich der Await Ausdruck in einem Block des Try Aufrufers, und die Ausnahme wird im Catch -Block abgefangen.

Heben Sie die Auskommentierung der Zeile Throw New Exception im Beispiel auf, um die Ausnahmebehandlung zu veranschaulichen. Die Ausnahme wird im Catch -Block abgefangen, die -Eigenschaft des Tasks IsFaulted wird auf True festgelegt, und die -Eigenschaft des Tasks Exception.InnerException wird auf die Ausnahme festgelegt.

Heben Sie die Auskommentierung der Zeile Throw New OperationCancelledException auf, um zu veranschaulichen, was beim Abbrechen eines asynchronen Prozesses passiert. Die Ausnahme wird im Catch -Block abgefangen, und die -Eigenschaft der Aufgabe IsCanceled ist auf True festgelegt. Unter einigen Bedingungen, die für dieses Beispiel nicht gelten, ist jedoch IsFaulted auf True und auf IsCanceled False festgelegt.

Public Async Function DoSomethingAsync() As Task
    Dim theTask As Task(Of String) = DelayAsync()

    Try
        Dim result As String = Await theTask
        Debug.WriteLine("Result: " & result)
    Catch ex As Exception
        Debug.WriteLine("Exception Message: " & ex.Message)
    End Try

    Debug.WriteLine("Task IsCanceled: " & theTask.IsCanceled)
    Debug.WriteLine("Task IsFaulted:  " & theTask.IsFaulted)
    If theTask.Exception IsNot Nothing Then
        Debug.WriteLine("Task Exception Message: " &
            theTask.Exception.Message)
        Debug.WriteLine("Task Inner Exception Message: " &
            theTask.Exception.InnerException.Message)
    End If
End Function

Private Async Function DelayAsync() As Task(Of String)
    Await Task.Delay(100)

    ' Uncomment each of the following lines to
    ' demonstrate exception handling.

    'Throw New OperationCanceledException("canceled")
    'Throw New Exception("Something happened.")
    Return "Done"
End Function


' Output when no exception is thrown in the awaited method:
'   Result: Done
'   Task IsCanceled: False
'   Task IsFaulted:  False

' Output when an Exception is thrown in the awaited method:
'   Exception Message: Something happened.
'   Task IsCanceled: False
'   Task IsFaulted:  True
'   Task Exception Message: One or more errors occurred.
'   Task Inner Exception Message: Something happened.

' Output when an OperationCanceledException or TaskCanceledException
' is thrown in the awaited method:
'   Exception Message: canceled
'   Task IsCanceled: True
'   Task IsFaulted:  False

Behandeln mehrerer Ausnahmen in asynchronen Methoden

Das folgende Beispiel veranschaulicht die Behandlung von Ausnahmen in Fällen, in denen mehrere Aufgaben zu mehreren Ausnahmen führen können. Der Try -Block verfügt über den Await Ausdruck für die Task.WhenAll zurückgegebene Aufgabe. Die Aufgabe ist abgeschlossen, wenn die drei Aufgaben, auf die Task.WhenAll angewendet wird, abgeschlossen sind.

Jede der drei Aufgaben löst eine Ausnahme aus. Der Catch -Block durchläuft die Ausnahmen, die in der Exception.InnerExceptions -Eigenschaft des zurückgegebenen Tasks gefunden Task.WhenAll werden.

Public Async Function DoMultipleAsync() As Task
    Dim theTask1 As Task = ExcAsync(info:="First Task")
    Dim theTask2 As Task = ExcAsync(info:="Second Task")
    Dim theTask3 As Task = ExcAsync(info:="Third Task")

    Dim allTasks As Task = Task.WhenAll(theTask1, theTask2, theTask3)

    Try
        Await allTasks
    Catch ex As Exception
        Debug.WriteLine("Exception: " & ex.Message)
        Debug.WriteLine("Task IsFaulted: " & allTasks.IsFaulted)
        For Each inEx In allTasks.Exception.InnerExceptions
            Debug.WriteLine("Task Inner Exception: " + inEx.Message)
        Next
    End Try
End Function

Private Async Function ExcAsync(info As String) As Task
    Await Task.Delay(100)

    Throw New Exception("Error-" & info)
End Function

' Output:
'   Exception: Error-First Task
'   Task IsFaulted: True
'   Task Inner Exception: Error-First Task
'   Task Inner Exception: Error-Second Task
'   Task Inner Exception: Error-Third Task

Weitere Informationen