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
isException
bijvoorbeeld: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:
Er wordt een eindinstructie aangetroffen in het
Try
ofCatch
blok.Er StackOverflowException wordt een in het
Try
ofCatch
blok gegooid.
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 Exception
is.
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 Sub
plaatsen. 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 True
en 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