Share via


Try...Catch...Finally Instructie (Visual Basic)

Biedt een manier om bepaalde of alle mogelijke fouten te verwerken die kunnen optreden in een bepaald codeblok, terwijl er nog steeds code wordt uitgevoerd.

Syntaxis

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

generator

Term Definitie
tryStatements Optioneel. Instructies waarin een fout kan optreden. Kan een samengestelde instructie zijn.
Catch Optioneel. Meerdere Catch blokken zijn toegestaan. Als er een uitzondering optreedt bij het verwerken van het Try blok, wordt elke Catch instructie in tekstuele volgorde onderzocht om te bepalen of deze de uitzondering verwerkt, waarbij exception de uitzondering wordt aangegeven die is gegenereerd.
exception Optioneel. Elke naam van een variabele. De oorspronkelijke waarde is exception de waarde van de gegenereerde fout. Wordt gebruikt om Catch de fout op te geven die is opgetreden. Als u dit weglaat, wordt in de Catch instructie een uitzondering onderschept.
type Optioneel. Hiermee geeft u het type klassefilter op. Als de waarde van exception het type is dat is opgegeven door type of van een afgeleid type, wordt de id gebonden aan het uitzonderingsobject.
When Optioneel. Een Catch instructie met een When component onderschept alleen uitzonderingen wanneer expression dit wordt geëvalueerd True. Een When component wordt pas toegepast nadat het type uitzondering is gecontroleerd en expression kan verwijzen naar de id die de uitzondering vertegenwoordigt.
expression Optioneel. Moet impliciet converteerbaar zijn naar Boolean. Elke expressie die een algemeen filter beschrijft. Wordt meestal gebruikt om te filteren op foutnummer. Wordt gebruikt met When trefwoord om omstandigheden op te geven waaronder de fout wordt opgetreden.
catchStatements Optioneel. Instructies voor het afhandelen van fouten die optreden in het bijbehorende Try blok. Kan een samengestelde instructie zijn.
Exit Try Optioneel. Trefwoord dat uit de Try...Catch...Finally structuur breekt. De uitvoering wordt hervat met de code direct na de End Try instructie. De Finally instructie wordt nog steeds uitgevoerd. Niet toegestaan in Finally blokken.
Finally Optioneel. Een Finally blok wordt altijd uitgevoerd wanneer de uitvoering een deel van de Try...Catch instructie verlaat.
finallyStatements Optioneel. Instructies die worden uitgevoerd nadat alle andere foutverwerking is opgetreden.
End Try Hiermee wordt de Try...Catch...Finally structuur beëindigd.

Opmerkingen

Als u verwacht dat een bepaalde uitzondering kan optreden tijdens een bepaalde codesectie, plaatst u de code in een Try blok en gebruikt u een Catch blok om de controle te behouden en de uitzondering te verwerken als deze zich voordoet.

Een Try…Catch instructie bestaat uit een Try blok gevolgd door een of meer Catch componenten, waarmee handlers voor verschillende uitzonderingen worden opgegeven. Wanneer er een uitzondering in een Try blok wordt gegenereerd, zoekt Visual Basic naar de Catch instructie die de uitzondering verwerkt. Als er geen overeenkomende Catch instructie wordt gevonden, onderzoekt Visual Basic de methode die de huidige methode wordt genoemd, enzovoort de aanroepstack. Als er geen Catch blok wordt gevonden, wordt in Visual Basic een niet-verwerkte uitzonderingsbericht weergegeven voor de gebruiker en wordt de uitvoering van het programma gestopt.

U kunt meer dan één Catch instructie in een Try…Catch instructie gebruiken. Als u dit doet, is de volgorde van de Catch componenten belangrijk omdat ze in volgorde worden onderzocht. Catch de meer specifieke uitzonderingen vóór de minder specifieke uitzonderingen.

De volgende Catch instructievoorwaarden zijn het minst specifiek en zijn catch alle uitzonderingen die zijn afgeleid van de Exception klasse. Normaal gesproken moet u een van deze variaties gebruiken als het laatste Catch blok in de Try...Catch...Finally structuur, na het ondervangen van alle specifieke uitzonderingen die u verwacht. Controlestroom kan nooit een Catch blok bereiken dat volgt op een van deze variaties.

  • Dit type is Exceptionbijvoorbeeld: Catch ex As Exception

  • De instructie heeft geen exception variabele, bijvoorbeeld: Catch

Wanneer een instructie in een Try…Catch…Finally ander Try blok is genest, onderzoekt Visual Basic eerst elke Catch instructie in het binnenste Try blok. Als er geen overeenkomende Catch instructie wordt gevonden, wordt de zoekopdracht uitgevoerd naar de Catch instructies van het buitenste Try…Catch…Finally blok.

Lokale variabelen van een Try blok zijn niet beschikbaar in een Catch blok omdat ze afzonderlijke blokken zijn. Als u een variabele in meer dan één blok wilt gebruiken, declareert u de variabele buiten de Try...Catch...Finally structuur.

Tip

De Try…Catch…Finally instructie is beschikbaar als een IntelliSense-codefragment. Vouw in codefragmentenbeheer codepatronen uit : If, For Each, TryCatchProperty, enzovoort, and then Error Handling (Exceptions). Zie Codefragmenten voor meer informatie.

Finally-blok

Als u een of meer instructies hebt die moeten worden uitgevoerd voordat u de Try structuur afsluit, gebruikt u een Finally blok. De besturing wordt doorgegeven aan het Finally blok net voordat het uit de Try…Catch structuur komt. Dit geldt zelfs als er ergens in de Try structuur een uitzondering optreedt.

Een Finally blok is handig voor het uitvoeren van code die moet worden uitgevoerd, zelfs als er een uitzondering is. Het besturingselement wordt doorgegeven aan het Finally blok, ongeacht hoe het Try...Catch blok wordt afgesloten.

De code in een Finally blok wordt uitgevoerd, zelfs als uw code een Return instructie in een Try of Catch blok tegenkomt. Het besturingselement wordt in de volgende gevallen niet van een Try of Catch blok doorgegeven aan het bijbehorende Finally blok:

Het is niet geldig om de uitvoering expliciet over te dragen naar een Finally blok. Het overdragen van de uitvoering uit een Finally blok is ongeldig, behalve via een uitzondering.

Als een Try instructie niet ten minste één Catch blok bevat, moet deze een Finally blok bevatten.

Tip

Als u geen specifieke uitzonderingen hoeft te catch maken, gedraagt de Using instructie zich als een Try…Finally blok en garandeert u de verwijdering van de resources, ongeacht hoe u het blok afsluit. Dit geldt zelfs met een onverwerkte uitzondering. Zie Using Statement voor meer informatie.

Uitzonderingsargument

Het Catch blokargument exception is een exemplaar van de Exception klasse of een klasse die is afgeleid van de Exception klasse. Het Exception klasse-exemplaar komt overeen met de fout die in het Try blok is opgetreden.

De eigenschappen van het Exception object helpen bij het identificeren van de oorzaak en locatie van een uitzondering. De StackTrace eigenschap bevat bijvoorbeeld de aangeroepen methoden die tot de uitzondering hebben geleid, zodat u kunt vinden waar de fout is opgetreden in de code. Message retourneert een bericht waarin de uitzondering wordt beschreven. HelpLink retourneert een koppeling naar een gekoppeld Help-bestand. InnerException retourneert het Exception object dat de huidige uitzondering heeft veroorzaakt, of retourneert Nothing het als er geen origineel Exceptionis.

Overwegingen bij het gebruik van een Try…Catch instructie

Gebruik een Try…Catch instructie alleen om het optreden van ongebruikelijke of onverwachte programmagebeurtenissen aan te geven. Redenen hiervoor zijn onder andere:

  • Het vangen van uitzonderingen tijdens runtime zorgt voor extra overhead en is waarschijnlijk langzamer dan het vooraf controleren om uitzonderingen te voorkomen.

  • Als een Catch blok niet correct wordt verwerkt, wordt de uitzondering mogelijk niet correct gerapporteerd aan gebruikers.

  • Uitzonderingsafhandeling maakt een programma complexer.

U hebt niet altijd een Try…Catch instructie nodig om te controleren op een voorwaarde die waarschijnlijk plaatsvindt. In het volgende voorbeeld wordt gecontroleerd of er een bestand bestaat voordat u het probeert te openen. Dit vermindert de noodzaak om een uitzondering te vangen die door de OpenText methode wordt gegenereerd.

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

Zorg ervoor dat code in Catch blokken uitzonderingen op de juiste wijze kan rapporteren aan gebruikers, of dit nu via thread-veilige logboekregistratie of de juiste berichten is. Anders blijven uitzonderingen mogelijk onbekend.

Asynchrone methoden

Als u een methode markeert met de Asynchrone modifier, kunt u de operator Await in de methode gebruiken. Een instructie met de operator onderbreekt de Await uitvoering van de methode totdat de wachtende taak is voltooid. De taak vertegenwoordigt doorlopend werk. Wanneer de taak die is gekoppeld aan de Await operator is voltooid, wordt de uitvoering hervat in dezelfde methode. Zie Controlestroom in Async-programma's voor meer informatie.

Een taak die wordt geretourneerd door een Async-methode, kan eindigen op een foutieve status, wat aangeeft dat deze is voltooid vanwege een niet-verwerkte uitzondering. Een taak kan ook eindigen op een geannuleerde status, wat tot gevolg heeft dat de OperationCanceledException wachtexpressie wordt weggegooid. Als u een van de typen uitzonderingen wilt catch gebruiken, plaatst u de Await expressie die is gekoppeld aan de taak in een Try blok en catch de uitzondering in het Catch blok. Verderop in dit onderwerp vindt u een voorbeeld.

Een taak kan een fout hebben omdat er meerdere uitzonderingen verantwoordelijk zijn voor de fout. De taak kan bijvoorbeeld het resultaat zijn van een aanroep naar Task.WhenAll. Wanneer u een dergelijke taak wacht, is de betrapte uitzondering slechts een van de uitzonderingen en kunt u niet voorspellen welke uitzondering wordt gevangen. Verderop in dit onderwerp vindt u een voorbeeld.

Een Await expressie kan zich niet in een Catch blok of Finally blok bevinden.

Iterators

Een iterator-functie of Get -toegangsfunctie voert een aangepaste iteratie uit op een verzameling. Een iterator gebruikt een Rendement-instructie om elk element van de verzameling één voor één te retourneren. U roept een iterator-functie aan met behulp van een For Each... Volgende instructie.

Een Yield instructie kan binnen een Try blok zitten. Een Try blok dat een Yield instructie bevat, kan blokken bevatten Catch en kan een Finally blok hebben. Zie Try Blokken voor een voorbeeld.

Een Yield instructie kan niet binnen een Catch blok of blok Finally staan.

Als de For Each hoofdtekst (buiten de iteratorfunctie) een uitzondering genereert, wordt een Catch blok in de iterator-functie niet uitgevoerd, maar wordt er een Finally blok in de iterator-functie uitgevoerd. Een Catch blok in een iteratorfunctie onderschept alleen uitzonderingen die voorkomen in de iteratorfunctie.

Gedeeltelijke vertrouwenssituaties

In gedeeltelijke vertrouwenssituaties, zoals een toepassing die wordt gehost op een netwerkshare, Try...Catch...Finally worden geen catch beveiligingsonderzonderingen uitgevoerd voordat de methode die de aanroep bevat, wordt aangeroepen. In het volgende voorbeeld wordt de fout 'System.Security.SecurityException: Request Failed' gegenereerd wanneer u deze op een servershare plaatst en daar wordt uitgevoerd. Zie de SecurityException klasse voor meer informatie over beveiligingsonderzondering.

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

In een dergelijke gedeeltelijke vertrouwenssituatie moet u de Process.Start verklaring afzonderlijk Subplaatsen. De eerste aanroep van de toepassing Sub mislukt. Dit maakt het mogelijk Try...Catch catch voordat de Sub inhoud Process.Start wordt gestart en de beveiligingsonderzondering wordt geproduceerd.

Voorbeelden

De structuur van Try...Catch...Finally

In het volgende voorbeeld ziet u de structuur van de Try...Catch...Finally instructie.

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.
        Console.WriteLine("end of Try block")
    Catch ex As Exception
        ' Show the exception's message.
        Console.WriteLine(ex.Message)

        ' Show the stack trace, which is a list of methods
        ' that are currently executing.
        Console.WriteLine("Stack Trace: " & vbCrLf & ex.StackTrace)
    Finally
        ' This line executes whether or not the exception occurs.
        Console.WriteLine("in Finally block")
    End Try
End Sub

Uitzondering in een methode die vanuit een blok wordt Try aangeroepen

In het volgende voorbeeld genereert de CreateException methode een NullReferenceException. De code waarmee de uitzondering wordt gegenereerd, bevindt zich niet in een Try blok. Daarom verwerkt de CreateException methode de uitzondering niet. De RunSample methode verwerkt de uitzondering omdat de aanroep van de CreateException methode zich in een Try blok bevindt.

Het voorbeeld bevat Catch instructies voor verschillende soorten uitzonderingen, geordend van de meest specifieke naar de meest algemene.

Public Sub RunSample()
    Try
        CreateException()
    Catch ex As System.IO.IOException
        ' Code that reacts to IOException.
    Catch ex As NullReferenceException
        Console.WriteLine("NullReferenceException: " & ex.Message)
        Console.WriteLine("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

De Catch instructie When

In het volgende voorbeeld ziet u hoe u een Catch When instructie gebruikt om te filteren op een voorwaardelijke expressie. Als de voorwaardelijke expressie wordt geëvalueerd True, wordt de code in het Catch blok uitgevoerd.

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

Geneste Try instructies

In het volgende voorbeeld ziet u een Try…Catch instructie die zich in een Try blok bevindt. Het binnenste Catch blok genereert een uitzondering waarvoor InnerException de eigenschap is ingesteld op de oorspronkelijke uitzondering. Het buitenste Catch blok rapporteert een eigen uitzondering en de binnenste uitzondering.

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

Afhandeling van uitzonderingen voor asynchrone methoden

In het volgende voorbeeld ziet u de verwerking van uitzonderingen voor asynchrone methoden. Voor catch een uitzondering die van toepassing is op een asynchrone taak, bevindt de Await expressie zich in een Try blok van de aanroeper en wordt de uitzondering in het Catch blok gevangen.

Verwijder opmerkingen bij de Throw New Exception regel in het voorbeeld om de verwerking van uitzonderingen te demonstreren. De uitzondering wordt in het Catch blok opgevangen, de eigenschap van IsFaulted de taak is ingesteld op Trueen de eigenschap van Exception.InnerException de taak is ingesteld op de uitzondering.

Verwijder opmerkingen bij de Throw New OperationCancelledException regel om te laten zien wat er gebeurt wanneer u een asynchroon proces annuleert. De uitzondering wordt in het Catch blok gevangen en de eigenschap van IsCanceled de taak is ingesteld op True. Onder bepaalde voorwaarden die niet van toepassing zijn op dit voorbeeld, IsFaulted wordt deze echter ingesteld True op en IsCanceled ingesteld op False.

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

Meerdere uitzonderingen verwerken in asynchrone methoden

In het volgende voorbeeld ziet u hoe uitzonderingen worden verwerkt, waarbij meerdere taken kunnen resulteren in meerdere uitzonderingen. Het Try blok heeft de Await expressie voor de geretourneerde taak Task.WhenAll . De taak is voltooid wanneer de drie taken waarop Task.WhenAll wordt toegepast, zijn voltooid.

Elk van de drie taken veroorzaakt een uitzondering. Het Catch blok doorloopt de uitzonderingen, die worden gevonden in de Exception.InnerExceptions eigenschap van de geretourneerde taak Task.WhenAll .

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

Zie ook