Try...Catch...Finally Utasítás (Visual Basic)
Lehetővé teszi egy adott kódblokkban esetlegesen előforduló hibák vagy hibák kezelését, miközben továbbra is futtatja a kódot.
Syntax
Try
[ tryStatements ]
[ Exit Try ]
[ Catch [ exception [ As type ] ] [ When expression ]
[ catchStatements ]
[ Exit Try ] ]
[ Catch ... ]
[ Finally
[ finallyStatements ] ]
End Try
Részek
Időszak | Definíció |
---|---|
tryStatements |
Opcionális. Utasítás(ok), ahol hiba léphet fel. Összetett utasítás is lehet. |
Catch |
Opcionális. Több Catch blokk engedélyezett. Ha a blokk feldolgozása során kivétel történik, az Try egyes Catch állításokat szöveges sorrendben vizsgáljuk meg annak megállapításához, hogy az kezeli-e a kivételt, a kidobott kivételt jelölve exception . |
exception |
Opcionális. Bármely változó neve. A kezdeti érték exception a kidobott hiba értéke. Catch A kifogott hiba megadására szolgál. Ha nincs megadva, az Catch utasítás kivételt észlel. |
type |
Opcionális. Megadja az osztályszűrő típusát. Ha az érték exception egy származtatott típus által type megadott vagy származtatott típus, akkor az azonosító a kivételobjektumhoz lesz kötve. |
When |
Opcionális. A Catch záradékkal rendelkező When utasítások csak akkor kapnak kivételt, ha expression a kiértékelés eredménye.True A When záradék csak a kivétel típusának ellenőrzése után lesz alkalmazva, és expression hivatkozhat a kivételt jelképező azonosítóra. |
expression |
Opcionális. Implicit módon konvertálhatónak Boolean kell lennie . Minden olyan kifejezés, amely általános szűrőt ír le. Általában hibaszám alapján történő szűrésre használják. Kulcsszóval When adhatja meg a hibát észlelő körülményeket. |
catchStatements |
Opcionális. Utasítás(ok) a társított Try blokkban előforduló hibák kezelésére. Összetett utasítás is lehet. |
Exit Try |
Opcionális. A szerkezetből Try...Catch...Finally kitörő kulcsszó. A végrehajtás az utasítást közvetlenül követő End Try kóddal folytatódik. Az Finally utasítás továbbra is végrehajtásra kerül. Blokkokban Finally nem engedélyezett. |
Finally |
Opcionális. A Finally blokkok mindig akkor lesznek végrehajtva, ha a Try...Catch végrehajtás az utasítás bármely részét elhagyja. |
finallyStatements |
Opcionális. Az összes többi hibafeldolgozás után végrehajtott utasítás(ok). |
End Try |
Leállítja a struktúrát Try...Catch...Finally . |
Megjegyzések
Ha arra számít, hogy egy adott kivétel a kód egy adott szakaszában fordulhat elő, helyezze a kódot egy Try
blokkba, és használjon blokkot Catch
a vezérlő megtartásához és a kivétel kezeléséhez, ha az előfordul.
Az Try…Catch
utasítás egy Try
blokkból és egy vagy több Catch
záradékból áll, amelyek különböző kivételek kezelőit határozzák meg. Ha kivételt ad egy Try
blokkba, a Visual Basic megkeresi a Catch
kivételt kezelő utasítást. Ha nem található egyező Catch
utasítás, a Visual Basic megvizsgálja az aktuális metódusnak nevezett metódust, és így tovább a hívási vermet. Ha nem Catch
található blokk, a Visual Basic nem kezelt kivételüzenetet jelenít meg a felhasználónak, és leállítja a program végrehajtását.
Egy utasításban Catch
több utasítást Try…Catch
is használhat. Ha ezt teszi, a záradékok sorrendje Catch
jelentős, mert a záradékok sorrendben vannak megvizsgálva. Catch a kevésbé specifikus kivételek előtt.
Az alábbi Catch
utasításfeltételek a legkevésbé specifikusak, és az osztályból Exception származó kivételeket is tartalmazni fogjákcatch. Általában ezen változatok egyikét kell használnia a struktúra utolsó Catch
blokkjaként Try...Catch...Finally
, miután elfogta az összes várt kivételt. A vezérlési folyamat soha nem érhet el olyan blokkot Catch
, amely bármelyik változatot követi.
Ez
type
például a következőException
:Catch ex As Exception
Az utasítás nem
exception
rendelkezik változóval, például:Catch
Ha egy utasítás egy Try…Catch…Finally
másik Try
blokkba van ágyazva, a Visual Basic először megvizsgálja a legbelső blokk összes Catch
utasítását Try
. Ha nem található egyező Catch
utasítás, a keresés a Catch
külső Try…Catch…Finally
blokk utasításaira folytatódik.
A Try
blokkok helyi változói nem érhetők el blokkokban Catch
, mert különálló blokkok. Ha több blokkban szeretne változót használni, deklarálja a változót a Try...Catch...Finally
struktúrán kívül.
Tipp.
Az Try…Catch…Finally
utasítás IntelliSense kódrészletként érhető el. A Kódrészletek kezelőjében bontsa ki a Kódminták – Ha, Mindegyik, TryCatchTulajdonság stb. elemet, majd a Hibakezelés (Kivételek) elemet. További információ: Kódrészletek.
Finally blokk
Ha egy vagy több utasítást kell futtatnia, mielőtt kilép a Try
struktúrából, használjon blokkot Finally
. A vezérlő átmegy a Finally
blokkra, mielőtt kimegy a Try…Catch
szerkezetből. Ez akkor is igaz, ha a struktúra bármely pontján Try
kivétel történik.
A Finally
blokkok akkor is hasznosak, ha olyan kódot futtatnak, amelyet kivétel esetén is végre kell hajtani. A vezérlőt a rendszer a Finally
blokk kilépési módjától függetlenül továbbítja a Try...Catch
blokknak.
A blokkokban lévő Finally
kód akkor is fut, ha a kód egy vagy Catch
több Return
blokkban lévő utasítást Try
talál. A vezérlő nem halad át egy Try
vagy Catch
több blokkból a megfelelő Finally
blokkba a következő esetekben:
A blokkban vagy
Catch
aTry
blokkban végponti utasítás található.A StackOverflowException be van dobva a
Try
blokkba.Catch
Nem érvényes a végrehajtás explicit átadása blokkba Finally
. A végrehajtás blokkból való átvitele Finally
nem érvényes, kivéve egy kivételt.
Ha egy Try
utasítás nem tartalmaz legalább egy Catch
blokkot, annak blokkot Finally
kell tartalmaznia.
Tipp.
Ha nincs szükség konkrét kivételekre catch , az Using
utasítás blokkként Try…Finally
viselkedik, és garantálja az erőforrások ártalmatlanítását, függetlenül attól, hogy hogyan lép ki a blokkból. Ez még kezeletlen kivétel esetén is igaz. További információ: Az utasítás használata.
Kivétel argumentuma
A Catch
blokkargumentum exception
az Exception osztály egy példánya, vagy egy osztály, amely az Exception
osztályból származik. Az Exception
osztálypéldány a blokkban Try
előforduló hibának felel meg.
Az objektum tulajdonságai Exception
segítenek azonosítani a kivétel okát és helyét. A tulajdonság például felsorolja azokat StackTrace az úgynevezett metódusokat, amelyek a kivételhez vezettek, és segítenek megtalálni, hogy hol történt a hiba a kódban. Message A kivételt leíró üzenetet ad vissza. HelpLink egy társított súgófájlra mutató hivatkozást ad vissza. InnerExceptionException
Az aktuális kivételt okozó objektumot adja visszaNothing
, vagy ha nincs eredetiException
.
Megfontolandó szempontok utasítás Try…Catch
használatakor
Csak utasítással Try…Catch
jelezheti a szokatlan vagy nem várt programesemények előfordulását. Ennek okai a következők:
A kivételek futásidőben történő elfogása további többletterhelést okoz, és valószínűleg lassabb, mint az előzetes ellenőrzés a kivételek elkerülése érdekében.
Ha egy
Catch
blokk kezelése nem megfelelően történik, előfordulhat, hogy a kivételt nem megfelelően jelenti a rendszer a felhasználóknak.A kivételkezelés összetettebbé teszi a programot.
Nem mindig van szüksége Try…Catch
utasításra egy valószínűleg előforduló feltétel ellenőrzéséhez. Az alábbi példa ellenőrzi, hogy létezik-e fájl a megnyitás előtt. Ez csökkenti a metódus által OpenText kidobott kivételek elfogásának szükségességét.
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
Győződjön meg arról, hogy a blokkokban lévő Catch
kód képes megfelelően jelenteni a felhasználók kivételeit, akár szálbiztos naplózással, akár megfelelő üzenetekkel. Ellenkező esetben előfordulhat, hogy a kivételek ismeretlenek maradnak.
Aszinkron metódusok
Ha az Async módosítóval jelöl meg egy metódust, használhatja a Metódus Várakozás operátorát. Az operátorral rendelkező Await
utasítás felfüggeszti a metódus végrehajtását, amíg a várt tevékenység be nem fejeződik. A tevékenység a folyamatban lévő munkát jelöli. Amikor az operátorhoz Await
társított feladat befejeződik, a végrehajtás ugyanabban a metódusban folytatódik. További információ: Control Flow in Async Programs.
Az Async-metódus által visszaadott feladat hibás állapotban végződhet, ami azt jelzi, hogy kezeletlen kivétel miatt fejeződött be. A tevékenységek megszakított állapotban is végződhetnek, ami azt eredményezi OperationCanceledException
, hogy a várt kifejezés ki lesz dobva. A catch kivétel bármelyik típusához helyezze a Await
tevékenységhez társított kifejezést egy Try
blokkba, a catch kivételt pedig a Catch
blokkba. A témakör későbbi részében egy példa látható.
A tevékenységek hibás állapotban lehetnek, mert több kivétel is felelős a hibákért. Előfordulhat például, hogy a feladat egy hívás Task.WhenAlleredménye. Ha egy ilyen feladatra vár, a kifogott kivétel csak az egyik kivétel, és nem tudja előre megjósolni, hogy melyik kivétel fog kifogni. A témakör későbbi részében egy példa látható.
A Await
kifejezések nem lehetnek blokkban vagy Finally
blokkbanCatch
.
Iterátorok
Egy iterátorfüggvény vagy Get
tartozék egyéni iterációt hajt végre egy gyűjteményen keresztül. Az iterátor egy Hozam utasítással egyenként adja vissza a gyűjtemény minden elemét. Iterátorfüggvényt hívhat meg minden egyeshöz... Következő utasítás.
Az Yield
utasítás egy blokkon belül Try
is lehet. Az Try
utasítást Yield
tartalmazó blokkok blokkokat tartalmazhatnak Catch
, és blokkokkal Finally
is rendelkezhetnek. Példa: Try Blokkok.
Az Yield
utasítás nem lehet blokkban Catch
vagy blokkban Finally
.
Ha a For Each
törzs (az iterátorfüggvényen kívül) kivételt jelez, Catch
az iterátorfüggvény blokkja nem lesz végrehajtva, de az iterátorfüggvény egy Finally
blokkja lesz végrehajtva. Az Catch
iterátorfüggvényen belüli blokkok csak az iterátorfüggvényben előforduló kivételeket rögzítik.
Részleges megbízhatósági helyzetek
Részleges megbízhatósági helyzetekben, például egy hálózati megosztáson üzemeltetett alkalmazás, nem catch jár biztonsági kivételekkel, Try...Catch...Finally
amelyek a hívást tartalmazó metódus meghívása előtt fordulnak elő. Az alábbi példa, amikor egy kiszolgálómegosztásra helyezi, és onnan futtatja, a következő hibát eredményezi: "System.Security.SecurityException: Request Failed". A biztonsági kivételekkel kapcsolatos további információkért tekintse meg az osztályt SecurityException .
Try
Process.Start("http://www.microsoft.com")
Catch ex As Exception
Console.WriteLine("Can't load Web page" & vbCrLf & ex.Message)
End Try
Ilyen részleges megbízhatósági helyzetben a nyilatkozatot külön Sub
kell elhelyeznie Process.Start
. A kezdeti hívás Sub
sikertelen lesz. Ez lehetővé teszi Try...Catch
, hogy catch a Sub
benne lévő Process.Start
fájl elinduljon, és a biztonsági kivétel létrejönjön.
Példák
A Try...Catch...Finally
Az alábbi példa az utasítás szerkezetét Try...Catch...Finally
mutatja be.
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
Kivétel blokkból Try
hívott metódusban
Az alábbi példában a CreateException
metódus egy NullReferenceException
. A kivételt létrehozó kód nincs blokkban Try
. Ezért a CreateException
metódus nem kezeli a kivételt. A RunSample
metódus kezeli a kivételt, mert a CreateException
metódus hívása blokkban Try
van.
A példa számos kivételtípusra vonatkozó utasításokat tartalmaz Catch
, amelyek a legkiváltabbtól a legátlagosabbaktól lesznek rendezve.
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
A Catch Mikor utasítás
Az alábbi példa bemutatja, hogyan használható utasítás egy Catch When
feltételes kifejezésre való szűréshez. Ha a feltételes kifejezés kiértékelése folyamatban True
van, a blokkban lévő Catch
kód lefut.
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
Try
Beágyazott utasítások
Az alábbi példa egy Try…Catch
blokkban található utasítással Try
rendelkezik. A belső Catch
blokk kivételt hoz létre, amelynek tulajdonsága InnerException
az eredeti kivételre van állítva. A külső Catch
blokk a saját kivételét és a belső kivételt jelenti.
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
Az aszinkron metódusok kivételkezelése
Az alábbi példa az aszinkron metódusok kivételkezelését mutatja be. Egy aszinkron tevékenységre vonatkozó kivétel esetén catch a Await
kifejezés a hívó blokkjában Try
van, és a kivétel a Catch
blokkban van.
Bontsa ki a Throw New Exception
példában szereplő sort a kivételkezelés bemutatásához. A kivétel a Catch
blokkban van, a tevékenység tulajdonsága IsFaulted
a kivételre van állítva True
, a tevékenység tulajdonsága Exception.InnerException
pedig a kivételre van állítva.
Bontsa ki a sort, Throw New OperationCancelledException
hogy bemuhassa, mi történik az aszinkron folyamat megszakításakor. A kivétel a Catch
blokkban van, és a tevékenység tulajdonsága IsCanceled
a következőre True
van állítva: . Bizonyos feltételek mellett azonban, amelyek nem vonatkoznak erre a példára, IsFaulted
a beállítás True
értéke a IsCanceled
False
következő.
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
Több kivétel kezelése az aszinkron metódusokban
Az alábbi példa a kivételkezelést mutatja be, ahol több tevékenység több kivételt eredményezhet. A Try
blokk a Await
visszaadott feladat Task.WhenAll kifejezésével rendelkezik. A tevékenység akkor fejeződik be, ha az alkalmazott három tevékenység Task.WhenAll befejeződött.
A három tevékenység mindegyike kivételt okoz. A Catch
blokk végigvezeti a kivételeket, amelyek a Exception.InnerExceptions
visszaadott feladat Task.WhenAll
tulajdonságában találhatók.
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