Try...Catch...Finally Příkaz (Visual Basic)

Poskytuje způsob, jak zpracovat některé nebo všechny možné chyby, ke kterým může docházet v daném bloku kódu, zatímco stále běží kód.

Syntaxe

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

Součástky

Pojem definice
tryStatements Nepovinné. Příkazy, u kterých může dojít k chybě. Může to být složený příkaz.
Catch Nepovinné. Je povoleno více Catch bloků. Pokud při zpracování Try bloku dojde k výjimce, je každý Catch příkaz zkoumán v textovém pořadí, aby zjistil, zda zpracovává výjimku, a exception představuje výjimku, která byla vyvolána.
exception Nepovinné. Libovolný název proměnné. Počáteční hodnota je hodnota exception vyvolané chyby. Catch Používá se k určení zachycené chyby. Pokud tento parametr vynecháte, Catch zachytí všechny výjimky.
type Nepovinné. Určuje typ filtru třídy. Pokud je hodnota exception typu určeného typem type nebo odvozeným typem, identifikátor se stane vázán na objekt výjimky.
When Nepovinné. Příkaz Catch s When klauzulí zachytává výjimky pouze v případech, kdy expression se vyhodnotí jako True. When Klauzule se použije pouze po kontrole typu výjimky a expression může odkazovat na identifikátor představující výjimku.
expression Nepovinné. Musí být implicitně konvertibilní na Boolean. Libovolný výraz, který popisuje obecný filtr. Obvykle se používá k filtrování podle čísla chyby. Používá se s klíčovým slovem When k určení okolností, za kterých se chyba zachytila.
catchStatements Nepovinné. Příkazy pro zpracování chyb, ke kterým dochází v přidruženém Try bloku. Může to být složený příkaz.
Exit Try Nepovinné. Klíčové slovo, které rozdělí Try...Catch...Finally strukturu. Provádění se obnoví kódem bezprostředně za příkazem End Try . Příkaz Finally bude stále proveden. Nepovoleno v Finally blocích.
Finally Nepovinné. Finally Blok se vždy spustí, když provádění opustí jakoukoli část Try...Catch příkazu.
finallyStatements Nepovinné. Příkazy, které se spustí po dokončení veškerého dalšího zpracování chyb.
End Try Ukončí Try...Catch...Finally strukturu.

Poznámky

Pokud očekáváte, že během konkrétní části kódu může dojít k určité výjimce, vložte kód do Try bloku a pomocí Catch bloku zachovejte kontrolu a zpracování výjimky, pokud k ní dojde.

Příkaz Try…Catch se skládá z Try bloku následovaného jednou nebo více Catch klauzulí, které určují obslužné rutiny pro různé výjimky. Pokud je v Try bloku vyvolán výjimka, Visual Basic hledá Catch příkaz, který zpracovává výjimku. Pokud se nenajde odpovídající Catch příkaz, Visual Basic prozkoumá metodu, která volala aktuální metodu, a tak dále nahoru zásobník volání. Pokud se nenajde žádný Catch blok, Visual Basic zobrazí neošetřenou zprávu o výjimce uživateli a zastaví spuštění programu.

V příkazu můžete použít více než jeden Catch příkaz Try…Catch . Pokud to uděláte, pořadí Catch klauzulí je významné, protože jsou zkoumány v pořadí. Catch konkrétnější výjimky před méně specifickými výjimkami.

Následující Catch podmínky příkazu jsou nejméně specifické a budou všechny catch výjimky odvozené z Exception třídy. Po zachycení všech konkrétních výjimek, které očekáváte, byste měli obvykle použít jednu z těchto variant jako poslední Catch blok struktury Try...Catch...Finally . Tok řízení se nikdy nemůže spojit s blokem, který následuje za některou Catch z těchto variant.

  • Jedná se type Exceptionnapříklad o: Catch ex As Exception

  • Příkaz nemá žádnou exception proměnnou, například: Catch

Try…Catch…Finally Když je příkaz vnořený do jiného Try bloku, Visual Basic nejprve prozkoumá každý Catch příkaz v nejvnitřnějším Try bloku. Pokud se nenajde žádný odpovídající Catch příkaz, vyhledávání pokračuje na Catch příkazy vnějšího Try…Catch…Finally bloku.

Místní proměnné z Try bloku nejsou v bloku k dispozici Catch , protože jsou samostatné bloky. Pokud chcete použít proměnnou ve více než jednom bloku, deklarujte proměnnou mimo Try...Catch...Finally strukturu.

Tip

Příkaz Try…Catch…Finally je k dispozici jako fragment kódu IntelliSense. Ve Správci fragmentů kódu rozbalte vzory kódu – If, For Each, TryCatch, Property atd. Pak zpracování chyb (výjimky). Další informace najdete v tématu Fragmenty kódu.

Blok Finally

Pokud máte jeden nebo více příkazů, které se musí spustit před ukončením Try struktury, použijte Finally blok. Řízení se předejde do Finally bloku těsně před tím, než vyjde ze Try…Catch struktury. To platí i v případě, že dojde k výjimce kdekoli uvnitř Try struktury.

Finally Blok je užitečný pro spuštění libovolného kódu, který se musí spustit, i když dojde k výjimce. Řízení se předává do Finally bloku bez ohledu na to, jak Try...Catch se blok ukončí.

Kód v Finally bloku se spustí i v případě, že váš kód narazí na Return příkaz v bloku Try nebo Catch bloku. Ovládací prvek nepřejde z odpovídajícího Try bloku do Catch odpovídajícího Finally bloku v následujícíchpřípadechch

  • Příkaz End je zjištěn v Try bloku nebo Catch v bloku.

  • A StackOverflowException je vyvolán v Try bloku nebo Catch v bloku.

Není platné explicitně převést provádění do Finally bloku. Přenos spuštění z Finally bloku není platný, s výjimkou výjimky.

Try Pokud příkaz neobsahuje aspoň jeden Catch blok, musí obsahovat Finally blok.

Tip

Pokud nemáte konkrétní catch výjimky, Using příkaz se chová jako Try…Finally blok a zaručuje odstranění prostředků bez ohledu na to, jak blok ukončíte. To platí i při neošetřené výjimce. Další informace naleznete v tématu Using – příkaz.

Argument výjimky

Argument Catch bloku exception je instance Exception třídy nebo třídy, která je odvozena od Exception třídy. Instance Exception třídy odpovídá chybě, ke které došlo v Try bloku.

Vlastnosti objektu Exception pomáhají identifikovat příčinu a umístění výjimky. StackTrace Například vlastnost uvádí volané metody, které vedly k výjimce, a pomáhá najít, kde došlo k chybě v kódu. Message vrátí zprávu, která popisuje výjimku. HelpLink vrátí odkaz na přidružený soubor nápovědy. InnerExceptionException vrátí objekt, který způsobil aktuální výjimku, nebo vrátíNothing, pokud neexistuje žádný původní Exception.

Důležité informace o použití Try…Catch příkazu

Try…Catch Příkaz použijte pouze k označení výskytu neobvyklých nebo neočekážených událostí programu. Mezi důvody patří:

  • Zachytávání výjimek za běhu vytváří další režii a pravděpodobně bude pomalejší než kontrola před kontrolou, aby nedocházelo k výjimkám.

  • Catch Pokud se blok nezpracuje správně, výjimka nemusí být uživatelům nahlášena správně.

  • Zpracovánívýjimekch

Vždy nepotřebujete Try…Catch příkaz ke kontrole podmínky, která by pravděpodobně nastala. Následující příklad zkontroluje, zda soubor existuje před pokusem o jeho otevření. To snižuje potřebu zachycení výjimky vyvolané metodou OpenText .

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

Ujistěte se, že kód v Catch blocích může uživatelům správně hlásit výjimky, ať už prostřednictvím protokolování bezpečného pro přístup z více vláken nebo vhodných zpráv. V opačném případě můžou výjimky zůstat neznámé.

Asynchronní metody

Pokud metodu označíte modifikátorem Async , můžete v metodě použít operátor Await . Příkaz s operátorem Await pozastaví provádění metody, dokud se neskončí očekávaný úkol. Úkol představuje probíhající práci. Když se úloha přidružená k operátoru Await dokončí, provádění se obnoví ve stejné metodě. Další informace naleznete v tématu Tok řízení v asynchronních programech.

Úloha vrácená asynchronní metodou může končit chybným stavem, což značí, že se dokončila kvůli neošetřené výjimce. Úkol může také končit zrušeným stavem, což vede OperationCanceledException k vyvolání výrazu await. Do catch některého typu výjimky umístěte Await výraz přidružený k úkolu do Try bloku a catch výjimku v Catch bloku. Příklad najdete dále v tomto tématu.

Úkol může být v chybném stavu, protože za jeho selhání zodpovídá více výjimek. Například úkol může být výsledkem volání Task.WhenAll. Když na takový úkol čekáte, chycená výjimka je pouze jednou z výjimek a nemůžete předpovědět, která výjimka se zachytí. Příklad najdete dále v tomto tématu.

Výraz Await nemůže být uvnitř Catch bloku nebo Finally bloku.

Iterátory

Funkce iterátoru nebo Get příslušenství provádí vlastní iteraci v kolekci. Iterátor používá příkaz Yield k vrácení každého prvku kolekce po jednom. Funkci iterátoru můžete volat pomocí funkce For Each... Next – příkaz.

Příkaz Yield může být uvnitř Try bloku. Try Blok, který obsahuje Yield příkaz, může obsahovat Catch bloky a může obsahovat Finally blok. Příklad najdete v tématu Try Bloky.

Příkaz Yield nemůže být uvnitř Catch bloku nebo Finally bloku.

For Each Pokud tělo (mimo funkci iterátoru) vyvolá výjimku, Catch nespustí se blok ve funkci iterátoru, ale Finally spustí se blok ve funkci iterátoru. Blok Catch uvnitř funkce iterátoru zachytává pouze výjimky, ke kterým dochází uvnitř funkce iterátoru.

Částečné vztahy důvěryhodnosti

V situacích s částečnou důvěryhodností, jako je například aplikace hostovaná ve sdílené síťové složce, Try...Catch...Finally nedojde catch k výjimkám zabezpečení, ke kterým dochází před vyvolání metody obsahující volání. Následující příklad, když ho umístíte do sdílené složky serveru a spustíte odsud, dojde k chybě System.Security.SecurityException: Požadavek se nezdařil. Další informace o výjimkách zabezpečení najdete ve SecurityException třídě.

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

V takové situaci s částečnou důvěrou musíte vložit Process.Start příkaz do samostatného Sub. Počáteční volání se Sub nezdaří. To mu umožní Try...Catch catch před spuštěním Sub souboru, který obsahuje Process.Start , a vygenerované výjimky zabezpečení.

Příklady

Struktura Try...Catch...Finally

Následující příklad znázorňuje strukturu Try...Catch...Finally příkazu.

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

Výjimka v metodě volané Try z bloku

V následujícím příkladu metoda CreateException vyvolá NullReferenceException. Kód, který vygeneruje výjimku, není v Try bloku. Proto metoda nezpracuje CreateException výjimku. Metoda RunSample zpracovává výjimku, protože volání CreateException metody je v Try bloku.

Příklad obsahuje Catch příkazy pro několik typů výjimek seřazených od nejvýraznějších po nejobecnější.

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

Příkaz Catch When

Následující příklad ukazuje, jak použít Catch When příkaz k filtrování podmíněného výrazu. Pokud se podmíněný výraz vyhodnotí jako True, kód v Catch bloku se spustí.

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

Vnořené Try příkazy

Následující příklad obsahuje Try…Catch příkaz, který je obsažen v Try bloku. Vnitřní Catch blok vyvolá výjimku, která má jeho InnerException vlastnost nastavenou na původní výjimku. Vnější Catch blok hlásí vlastní výjimku a vnitřní výjimku.

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

Zpracování výjimek pro asynchronní metody

Následující příklad znázorňuje zpracování výjimek pro asynchronní metody. Na catch výjimku, která se vztahuje na asynchronní úlohu, Await je výraz v Try bloku volajícího a výjimka je zachycena Catch v bloku.

Odkomentujte řádek v příkladu a předveďte Throw New Exception zpracování výjimek. Výjimka je zachycena Catch v bloku, vlastnost úkolu IsFaulted je nastavena na Truea vlastnost úkolu Exception.InnerException je nastavena na výjimku.

Odkomentujte Throw New OperationCancelledException řádek, abyste ukázali, co se stane, když zrušíte asynchronní proces. Výjimka je zachycena Catch v bloku a vlastnost úkolu IsCanceled je nastavena na True. Nicméně za určitých podmínek, které se nevztahují na tento příklad, je nastavena True na a IsCanceled je nastavena na False. IsFaulted

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

Zpracování více výjimek v asynchronních metodách

Následující příklad znázorňuje zpracování výjimek, kdy více úloh může vést k několika výjimkám. Blok Try obsahuje Await výraz pro vrácenou úlohu Task.WhenAll . Úkol je dokončen, když jsou dokončeny tři úkoly, na které Task.WhenAll se použijí.

Každý ze tří úkolů způsobí výjimku. Blok Catch iteruje prostřednictvím výjimek, které jsou nalezeny ve Exception.InnerExceptions vlastnosti úkolu, který Task.WhenAll vrátil.

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

Viz také