Try...Catch...Finally Instruktion (Visual Basic)
Ger ett sätt att hantera vissa eller alla möjliga fel som kan uppstå i ett visst kodblock medan koden fortfarande körs.
Syntax
Try
[ tryStatements ]
[ Exit Try ]
[ Catch [ exception [ As type ] ] [ When expression ]
[ catchStatements ]
[ Exit Try ] ]
[ Catch ... ]
[ Finally
[ finallyStatements ] ]
End Try
Delar
Period | Definition |
---|---|
tryStatements |
Valfritt. Instruktioner där ett fel kan inträffa. Kan vara en sammansatt sats. |
Catch |
Valfritt. Flera Catch block tillåts. Om ett undantag inträffar vid bearbetning av Try blocket granskas varje Catch -instruktion i textordning för att avgöra om undantaget hanteras, med exception ett undantag som representerar det undantag som har genererats. |
exception |
Valfritt. Valfritt variabelnamn. Det initiala värdet exception för är värdet för det utlöses-felet. Används med Catch för att ange felet fångas. Om den utelämnas fångar instruktionen Catch upp alla undantag. |
type |
Valfritt. Anger typ av klassfilter. Om värdet för exception är av den typ som anges av type eller av en härledd typ, blir identifieraren bunden till undantagsobjektet. |
When |
Valfritt. En Catch instruktion med en When sats fångar endast undantag när expression utvärderas till True . En When sats tillämpas endast efter att ha kontrollerat typen av undantag och expression kan referera till identifieraren som representerar undantaget. |
expression |
Valfritt. Måste implicit konverteras till Boolean . Alla uttryck som beskriver ett allmänt filter. Används vanligtvis för att filtrera efter felnummer. Används med When nyckelord för att ange omständigheter under vilka felet fångas. |
catchStatements |
Valfritt. Instruktioner för att hantera fel som inträffar i det associerade Try blocket. Kan vara en sammansatt sats. |
Exit Try |
Valfritt. Nyckelord som bryter ut ur Try...Catch...Finally strukturen. Körningen återupptas med koden omedelbart efter -instruktionen End Try . -instruktionen Finally kommer fortfarande att köras. Tillåts inte i Finally block. |
Finally |
Valfritt. Ett Finally block körs alltid när körningen lämnar någon del av -instruktionen Try...Catch . |
finallyStatements |
Valfritt. Instruktioner som körs efter att all annan felbearbetning har inträffat. |
End Try |
Try...Catch...Finally Avslutar strukturen. |
Kommentarer
Om du förväntar dig att ett visst undantag kan inträffa under ett visst kodavsnitt placerar du koden i ett Try
block och använder ett Catch
block för att behålla kontrollen och hantera undantaget om det inträffar.
En Try…Catch
instruktion består av ett Try
block följt av en eller flera Catch
satser, som anger hanterare för olika undantag. När ett undantag utlöses i ett Try
block letar Visual Basic efter instruktionen Catch
som hanterar undantaget. Om en matchande Catch
instruktion inte hittas undersöker Visual Basic metoden som anropade den aktuella metoden och så vidare upp anropsstacken. Om inget Catch
block hittas visar Visual Basic ett ohanterat undantagsmeddelande till användaren och stoppar körningen av programmet.
Du kan använda mer än en Catch
instruktion i en Try…Catch
-instruktion. Om du gör detta är ordningen på klausulerna Catch
betydande eftersom de granskas i ordning. Catch de mer specifika undantagen före de mindre specifika.
Följande Catch
instruktionsvillkor är de minst specifika och kommer alla catch undantag som härleds från Exception klassen. Du bör vanligtvis använda en av dessa varianter som det sista Catch
blocket i Try...Catch...Finally
strukturen, efter att du har fångat alla specifika undantag som du förväntar dig. Kontrollflödet kan aldrig nå ett Catch
block som följer någon av dessa varianter.
type
ärException
, till exempel:Catch ex As Exception
-instruktionen har ingen
exception
variabel, till exempel:Catch
När en Try…Catch…Finally
instruktion är kapslad i ett annat Try
block undersöker Visual Basic först varje Catch
instruktion i det innersta Try
blocket. Om ingen matchande Catch
instruktion hittas fortsätter sökningen till uttrycken Catch
i det yttre Try…Catch…Finally
blocket.
Lokala variabler från ett Try
block är inte tillgängliga i ett Catch
block eftersom de är separata block. Om du vill använda en variabel i mer än ett block deklarerar du variabeln utanför Try...Catch...Finally
strukturen.
Dricks
-instruktionen Try…Catch…Finally
är tillgänglig som ett IntelliSense-kodfragment. I Kodfragmenthanteraren expanderar du Kodmönster – Om, För varje,CatchTry , Egenskap osv. och sedan Felhantering (undantag). Mer information finns i Kodfragment.
Finally blockera
Om du har en eller flera instruktioner som måste köras innan du avslutar Try
strukturen använder du ett Finally
block. Kontrollen skickas Finally
till blocket precis innan den skickas Try…Catch
ut ur strukturen. Detta gäller även om ett undantag inträffar någonstans i Try
strukturen.
Ett Finally
block är användbart för att köra kod som måste köras även om det finns ett undantag. Kontrollen skickas till Finally
blocket oavsett hur Try...Catch
blocket avslutas.
Koden i ett Finally
block körs även om koden påträffar en Return
-instruktion i ett Try
eller Catch
ett block. Kontrollen skickas inte från ett Try
eller Catch
blockera till motsvarande Finally
block i följande fall:
Ett slututtryck påträffas i
Try
ellerCatch
-blocket.A StackOverflowException kastas i
Try
ellerCatch
blocket.
Det är inte giltigt att uttryckligen överföra körningen till ett Finally
block. Överföring av körning från ett Finally
block är inte giltigt, förutom genom ett undantag.
Om en Try
instruktion inte innehåller minst ett Catch
block måste den innehålla ett Finally
block.
Dricks
Om du inte behöver catch specifika undantag fungerar -instruktionen Using
som ett Try…Finally
block och garanterar bortskaffande av resurserna, oavsett hur du avslutar blocket. Detta gäller även med ett ohanterat undantag. Mer information finns i Använda instruktion.
Undantagsargument
Blockargumentet Catch
exception
är en instans av Exception klassen eller en klass som härleds från Exception
klassen. Klassinstansen Exception
motsvarar felet som inträffade i Try
blocket.
Egenskaperna för Exception
objektet hjälper dig att identifiera orsaken till och platsen för ett undantag. Egenskapen listar till exempel StackTrace de metoder som ledde till undantaget, vilket hjälper dig att hitta var felet inträffade i koden. Message returnerar ett meddelande som beskriver undantaget. HelpLink returnerar en länk till en associerad hjälpfil. InnerException returnerar objektet Exception
som orsakade det aktuella undantaget eller returnerar Nothing
om det inte finns någon ursprunglig Exception
.
Överväganden när du använder en Try…Catch
instruktion
Använd endast en Try…Catch
instruktion för att signalera förekomsten av ovanliga eller oväntade programhändelser. Orsaker till detta är bland annat följande:
Att fånga undantag vid körning skapar ytterligare omkostnader och kommer sannolikt att vara långsammare än förkontroll för att undvika undantag.
Om ett
Catch
block inte hanteras korrekt kanske undantaget inte rapporteras korrekt till användarna.Undantagshantering gör ett program mer komplext.
Du behöver inte alltid en Try…Catch
-instruktion för att söka efter ett villkor som sannolikt kommer att inträffa. I följande exempel kontrolleras om en fil finns innan du försöker öppna den. Detta minskar behovet av att fånga ett undantag som genereras av OpenText metoden.
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
Se till att kod i Catch
block korrekt kan rapportera undantag till användare, oavsett om det gäller trådsäker loggning eller lämpliga meddelanden. Annars kan undantag förbli okända.
Asynkrona metoder
Om du markerar en metod med Async-modifieraren kan du använda Operatorn Await i -metoden. En instruktion med operatorn Await
pausar körningen av metoden tills den väntande aktiviteten har slutförts. Uppgiften representerar pågående arbete. När aktiviteten som är associerad med operatorn Await
är klar återupptas körningen med samma metod. Mer information finns i Kontrollera flöde i Async-program.
En uppgift som returneras av en Async-metod kan sluta i ett felaktigt tillstånd, vilket indikerar att den slutfördes på grund av ett ohanterat undantag. En uppgift kan också sluta i ett avbrutet tillstånd, vilket resulterar i att en OperationCanceledException
utlöses från det väntande uttrycket. Om du vill catch använda någon av undantagstyperna placerar du uttrycket Await
som är associerat med uppgiften i ett Try
block och catch undantaget i blocket Catch
. Ett exempel visas senare i det här avsnittet.
En uppgift kan vara i ett feltillstånd eftersom flera undantag var ansvariga för dess fel. Uppgiften kan till exempel vara resultatet av ett anrop till Task.WhenAll. När du väntar på en sådan uppgift är det fångade undantaget bara ett av undantagen och du kan inte förutsäga vilket undantag som ska fångas. Ett exempel visas senare i det här avsnittet.
Ett Await
uttryck får inte finnas i ett Catch
block eller Finally
block.
Iteratorer
En iteratorfunktion eller Get
-accessor utför en anpassad iteration över en samling. En iterator använder en Yield-instruktion för att returnera varje element i samlingen en i taget. Du anropar en iteratorfunktion med hjälp av en För varje... Nästa instruktion.
En Yield
instruktion kan finnas i ett Try
block. Ett Try
block som innehåller en Yield
-instruktion kan ha Catch
block och kan ha ett Finally
block. Ett exempel finns i Try Block.
En Yield
instruktion får inte finnas i ett Catch
block eller ett Finally
block.
Om brödtexten For Each
(utanför iteratorfunktionen) utlöser ett undantag körs inte ett Catch
block i iteratorfunktionen, men ett Finally
block i iteratorfunktionen körs. Ett Catch
block i en iteratorfunktion fångar bara upp undantag som inträffar i iteratorfunktionen.
Situationer med partiellt förtroende
I situationer med partiellt förtroende, till exempel ett program som finns på en nätverksresurs, Try...Catch...Finally
sker inte catch säkerhetsfel som inträffar innan metoden som innehåller anropet anropas. I följande exempel, när du placerar den på en serverresurs och kör därifrån, uppstår felet "System.Security.SecurityException: Begäran misslyckades". Mer information om säkerhetsfel finns i SecurityException klassen .
Try
Process.Start("http://www.microsoft.com")
Catch ex As Exception
Console.WriteLine("Can't load Web page" & vbCrLf & ex.Message)
End Try
I en sådan partiell förtroendesituation måste du placera -instruktionen Process.Start
i en separat Sub
. Det första anropet Sub
till kommer att misslyckas. Detta gör det möjligt Try...Catch
innan catch som Sub
innehåller startas Process.Start
och säkerhetsfelet skapas.
Exempel
Strukturen för Try...Catch...Finally
I följande exempel visas instruktionens Try...Catch...Finally
struktur.
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
Undantag i en metod som anropas från ett Try
block
I följande exempel CreateException
genererar metoden en NullReferenceException
. Koden som genererar undantaget finns inte i ett Try
block. CreateException
Därför hanterar metoden inte undantaget. Metoden RunSample
hanterar undantaget eftersom anropet CreateException
till metoden är i ett Try
block.
Exemplet innehåller Catch
instruktioner för flera typer av undantag, ordnade från de mest specifika till de mest allmänna.
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
Instruktionen Catch När
I följande exempel visas hur du använder en Catch When
-instruktion för att filtrera på ett villkorsuttryck. Om villkorsuttrycket utvärderas till True
körs koden i Catch
blocket.
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
Kapslade Try
uttryck
I följande exempel finns en Try…Catch
-instruktion som finns i ett Try
block. Det inre Catch
blocket genererar ett undantag som har dess InnerException
egenskap inställd på det ursprungliga undantaget. Det yttre Catch
blocket rapporterar sitt eget undantag och det inre undantaget.
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
Undantagshantering för asynkrona metoder
I följande exempel visas undantagshantering för asynkrona metoder. För catch ett undantag som gäller för en asynkron aktivitet Await
finns uttrycket i ett Try
block av anroparen och undantaget fångas i Catch
blocket.
Ta bort kommentaren till Throw New Exception
raden i exemplet för att demonstrera undantagshantering. Undantaget fångas i Catch
blocket, aktivitetens IsFaulted
egenskap är inställd på True
och aktivitetens Exception.InnerException
egenskap är inställd på undantaget.
Ta bort kommentaren till Throw New OperationCancelledException
raden för att visa vad som händer när du avbryter en asynkron process. Undantaget fångas i Catch
blocket och aktivitetens IsCanceled
egenskap är inställd på True
. Men under vissa villkor som inte gäller för det här exemplet IsFaulted
är inställt på True
och IsCanceled
är inställt på 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
Hantera flera undantag i asynkrona metoder
I följande exempel visas undantagshantering där flera uppgifter kan resultera i flera undantag. Blocket Try
har uttrycket Await
för den uppgift som Task.WhenAll returnerades. Uppgiften är slutförd när de tre aktiviteter som Task.WhenAll tillämpas är slutförda.
Var och en av de tre uppgifterna orsakar ett undantag. Blocket Catch
itererar genom undantagen, som finns i Exception.InnerExceptions
egenskapen för den uppgift som Task.WhenAll
returnerades.
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