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 code weiterhin 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. Anweisung(n) wo ein Fehler auftreten kann. Kann eine Verbundanweisung sein.
Catch Optional. Mehrere Catch Blöcke zulässig. Wenn eine Ausnahme beim Verarbeiten des Try Blocks auftritt, wird jede Catch Anweisung in textualer Reihenfolge untersucht, um festzustellen, ob die Ausnahme behandelt wird, wobei exception die Ausnahme dargestellt wird, die ausgelöst wurde.
exception Optional. Ein beliebiger Variablenname. Der Anfangswert von exception ist der Wert des ausgelösten Fehlers. Wird verwendet, Catch um den Fehler anzugeben, der erfasst wurde. Wenn nicht angegeben, erfasst die Catch Anweisung eine Ausnahme.
type Optional. Gibt den Typ des Klassenfilters an. Wenn der Wert exception des von oder eines abgeleiteten Typs angegebenen type Typs ist, wird der Bezeichner an das Ausnahmeobjekt gebunden.
When Optional. Eine Catch Anweisung mit einer When Klausel erfasst Ausnahmen nur, wenn expression sie ausgewertet werden True. Eine When Klausel wird nur nach der Überprüfung des Typs der Ausnahme angewendet und expression kann auf den Bezeichner verweisen, der die Ausnahme darstellt.
expression Optional. Muss implizit umverwandelt werden.Boolean Jeder Ausdruck, der einen generischen Filter beschreibt. In der Regel wird verwendet, um nach Fehlernummer zu filtern. Wird mit When Schlüsselwort verwendet, um Umstände anzugeben, unter denen der Fehler erfasst wird.
catchStatements Optional. Anweisungen, um Fehler zu behandeln, die im zugeordneten Try Block auftreten. Kann eine Verbundanweisung sein.
Exit Try Optional. Schlüsselwort, das aus der Try...Catch...Finally Struktur herausbricht. Die Ausführung wird mit dem Code unmittelbar nach der End Try Anweisung fortgesetzt. Die Finally Anweisung wird weiterhin ausgeführt. Nicht zulässig in Finally Blöcken.
Finally Optional. Ein Finally Block wird immer ausgeführt, wenn die Ausführung einen Teil der Try...Catch Anweisung verlässt.
finallyStatements Optional. Anweisungen, die ausgeführt werden, nachdem alle anderen Fehlerverarbeitungen aufgetreten sind.
End Try Beendet die Try...Catch...Finally Struktur.

Hinweise

Wenn Sie erwarten, dass während eines bestimmten Codeabschnitts eine bestimmte Ausnahme auftreten kann, setzen Sie den Code in einen Try Block, und verwenden Sie einen Catch Block, um Kontrolle beizubehalten und die Ausnahme zu behandeln, wenn sie auftritt.

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

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

Die folgenden Catch Anweisungsbedingungen sind die wenigsten spezifischen Und werden alle Ausnahmen abfangen, die aus der Exception Klasse abgeleitet werden. Sie sollten eine dieser Variationen als letzten Catch Block in der Try...Catch...Finally Struktur verwenden, nachdem Sie alle von Ihnen erwarteten spezifischen Ausnahmen abfangen. Der Steuerungsfluss kann niemals einen Block erreichen, der einer Catch dieser Variationen folgt.

  • Dies type ist z. B Exception. folgendes: Catch ex As Exception

  • Die Anweisung hat keine exception Variable, z. B.: Catch

Wenn eine Try…Catch…Finally Anweisung in einem anderen Try Block geschachtelt ist, überprüft Visual Basic zunächst jede Catch Anweisung im innersten Try Block. Wenn keine übereinstimmende Catch Anweisung gefunden wird, wird die Suche an die Catch Anweisungen des äußeren Try…Catch…Finally Blocks fortgesetzt.

Lokale Variablen aus einem Block sind in einem TryCatch Block nicht verfügbar, da sie separate Blöcke sind. 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 – Wenn, für jede, Versuchen Sie Fangen, Eigenschaft usw., und dann fehlerbehandlung (Ausnahmen). Weitere Informationen finden Sie unter Codeausschnitte.

Abschließender Block

Wenn Sie über eine oder mehrere Anweisungen verfügen, die ausgeführt werden müssen, bevor Sie die Try Struktur beenden, verwenden Sie einen Finally Block. Steuerelement wird an den Finally Block übergeben, bevor er aus der Try…Catch Struktur ausläuft. Dies gilt auch dann, wenn eine Ausnahme irgendwo innerhalb der Try Struktur auftritt.

Ein Finally Block ist nützlich für das Ausführen eines Codes, der ausgeführt werden muss, auch wenn eine Ausnahme vorhanden ist. Das Steuerelement wird an den Finally Block übergeben, unabhängig davon, wie der Try...Catch Block beendet wird.

Der Code in einem Block wird auch ausgeführt, wenn der Code eine Return Anweisung in einem TryFinally oder Catch block auftritt. Das Steuerelement wird nicht von einem TryCatch oder einem Block an den entsprechenden Finally Block in den folgenden Fällen übergeben:

Es gilt nicht, die Ausführung explizit in einen Finally Block zu übertragen. Die Übertragung der Ausführung aus einem Finally Block ist nicht gültig, außer durch eine Ausnahme.

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

Tipp

Wenn Sie keine bestimmten Ausnahmen erfassen müssen, verhält sich die Using Anweisung wie ein Try…Finally Block und garantiert die Entsorgung der Ressourcen, unabhängig davon, wie Sie den Block beenden. Dies gilt sogar mit einer unhandigen Ausnahme. Weitere Informationen finden Sie unter using-Anweisung.

Ausnahmeargument

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

Die Eigenschaften des Exception Objekts helfen, die Ursache und position einer Ausnahme zu identifizieren. Die Eigenschaft listet beispielsweise StackTrace die aufgerufenen Methoden auf, die zu der Ausnahme geführt haben, damit Sie suchen, wo der Fehler im Code aufgetreten ist. Message gibt eine Nachricht zurück, die die Ausnahme beschreibt. HelpLink Gibt einen Link zu einer zugeordneten Hilfedatei zurück. InnerException gibt das Exception Objekt zurück, das die aktuelle Ausnahme verursacht hat, oder es wird zurückgegeben Nothing , wenn kein Original Exceptionvorhanden ist.

Überlegungen beim Verwenden eines Try... Catch-Anweisung

Verwenden Sie eine Try…Catch Anweisung nur, um das Auftreten von ungewöhnlichen oder unvorgesehenen Programmereignissen zu signalisieren. Gründe für dies sind die folgenden:

  • Das Erfassen von Ausnahmen zur Laufzeit erstellt zusätzlichen Aufwand 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.

  • Die Ausnahmebehandlung macht ein Programm komplexer.

Sie benötigen nicht immer eine Try…Catch Anweisung, um nach einer Bedingung zu suchen, die wahrscheinlich auftritt. Im folgenden Beispiel wird überprüft, ob eine Datei vorhanden ist, bevor Sie versuchen, es zu öffnen. Dies reduziert die Notwendigkeit, eine Ausnahme zu erfassen, die von der OpenText Methode 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 Ausnahmen für Benutzer ordnungsgemäß melden kann, unabhängig davon, ob durch threadsichere Protokollierung oder entsprechende Nachrichten. Andernfalls bleiben Ausnahmen möglicherweise unbekannt.

Asynchrone Methoden

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

Eine aufgabe, die von einer Async-Methode zurückgegeben wird, kann in einem fehlerhaften Zustand enden, der angibt, dass es aufgrund einer nicht behandelten Ausnahme abgeschlossen wurde. Eine Aufgabe kann auch in einem abgebrochenen Zustand enden, der dazu führt, dass ein OperationCanceledException Abbruch des wartenden Ausdrucks ausgelöst wird. Um einen Ausnahmetyp zu erfassen, platzieren Sie den Await Ausdruck, der dem Vorgang in einem Try Block zugeordnet ist, und fangen Sie die Ausnahme im Catch Block ab. Ein Beispiel wird später in diesem Thema bereitgestellt.

Eine Aufgabe kann sich in einem fehlerhaften Zustand befinden, da mehrere Ausnahmen für ihre Fehler verantwortlich waren. Beispielsweise kann die Aufgabe das Ergebnis eines Aufrufs an Task.WhenAll sein. Wenn Sie eine solche Aufgabe erwarten, ist die gefangene Ausnahme nur eine der Ausnahmen, und Sie können nicht voraussagen, welche Ausnahme erfasst wird. Ein Beispiel wird später in diesem Thema bereitgestellt.

Ein Await Ausdruck kann nicht in einem Catch Block oder Finally Block enthalten sein.

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 gleichzeitig zurückzugeben. Sie rufen eine Iteratorfunktion mithilfe einer For Each-Funktion auf... Nächste Anweisung.

Eine Yield Anweisung kann sich innerhalb eines Try Blocks befinden. Ein Try Block, der eine Yield Anweisung enthält, kann Catch Blöcke aufweisen und einen Finally Block haben. Weitere Informationen finden Sie im Abschnitt "Testen von Blöcken in Visual Basic" von Iteratoren für ein Beispiel.

Eine Yield Anweisung kann nicht in einem Block oder einem FinallyCatch Block enthalten sein.

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

Teilvertrauenswürdige Situationen

In teilvertrauenswürdigen Situationen, z. B. einer Anwendung, die in einer Netzwerkfreigabe gehostet wird, werden keine Sicherheits ausnahmen erfasst, die vor dem Aufrufen der Methode auftreten, Try...Catch...Finally die den Aufruf enthält. Im folgenden Beispiel wird der Fehler "System.Security.SecurityException: Anforderung fehlgeschlagen" generiert, wenn Sie es auf eine Serverfreigabe setzen und dort ausführen. 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 teilvertrauenswürdigen Situation müssen Sie die Process.Start Anweisung in eine separate SubEinstellung setzen. Der anfängliche Aufruf des Vorgangs Sub schlägt fehl. Dies ermöglicht Try...Catch es, sie zu erfassen, bevor die Sub enthaltene Process.Start Datei gestartet wird und die sicherheitsbezogene Ausnahme erstellt wurde.

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. 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 mehrere Arten von Ausnahmen, die von der spezifischsten bis zum allgemeinsten angeordnet sind.

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

Im folgenden Beispiel wird gezeigt, wie Sie eine Catch When Anweisung verwenden, um auf einen bedingten Ausdruck zu filtern. Wenn der bedingte Ausdruck Trueausgewertet wird, 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

Im folgenden Beispiel wird eine Try…Catch Anweisung angegeben, die in einem Try Block enthalten ist. Der innere Catch Block löst eine Ausnahme aus, die seine InnerException Eigenschaft auf die ursprüngliche Ausnahme festgelegt hat. 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 zu erfassen, die für eine asynchrone Aufgabe gilt, befindet sich der Await Ausdruck in einem Try Block des Aufrufers, und die Ausnahme wird im Catch Block erfasst.

Heben Sie die Auskommentierung der Zeile Throw New Exception im Beispiel auf, um die Ausnahmebehandlung zu veranschaulichen. Die Ausnahme wird im Catch Block erfasst, die Eigenschaft des Vorgangs wird auf True"" festgelegt, und die Eigenschaft des Vorgangs IsFaultedException.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 Block erfasst, und die Eigenschaft des Catch Vorgangs IsCanceled wird auf True"festgelegt" festgelegt. Unter einigen Bedingungen, die sich nicht auf dieses Beispiel beziehen, IsFaulted ist True auf und wird auf False"festgelegt" festgelegt.IsCanceled

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 hat den Await Ausdruck für die aufgabe, die Task.WhenAll zurückgegeben wurde. Die Aufgabe wird abgeschlossen, wenn die drei Aufgaben abgeschlossen sind, auf Task.WhenAll die angewendet wird.

Jede der drei Aufgaben löst eine Ausnahme aus. Der Catch Block durch die Ausnahmen, die in der Exception.InnerExceptions Eigenschaft der zurückgegebenen Aufgabe Task.WhenAll gefunden 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