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 dojít v daném bloku kódu při stále spuštěném kódu.

Syntax

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

Součásti

Pojem Definice
tryStatements Nepovinný parametr. Příkaz nebo příkaz, u kterých může dojít k chybě. Může to být složený příkaz.
Catch Nepovinný parametr. Povolených Catch více bloků. Pokud při zpracování bloku dojde k výjimce, každý příkaz je prozkoumán v textovém pořadí, aby bylo možné určit, zda zpracovává výjimku, s reprezentací výjimky, která Try Catch byla exception vyvolána.
exception Nepovinný parametr. Libovolný název proměnné. Počáteční hodnota je exception hodnota vyvolané chyby. Používá se Catch s k určení zachycené chyby. Pokud je vynechán, příkaz Catch zachytí jakoukoli výjimku.
type Nepovinný parametr. Určuje typ filtru třídy. Pokud je hodnota typu určená parametrem nebo odvozeného typu, identifikátor se exception type sváže s objektem výjimky.
When Nepovinný parametr. Příkaz Catch s klauzulí When zachycuje výjimky pouze v expression případě, že je vyhodnocen jako True . Klauzule se použije až po kontrole typu výjimky a může odkazovat na When expression identifikátor představující výjimku.
expression Nepovinný parametr. Musí být implicitně převoditelné na Boolean . Libovolný výraz, který popisuje obecný filtr. Obvykle se používá k filtrování podle čísla chyby. Používá se s When klíčovým slovem k určení okolností, za kterých je chyba zachycena.
catchStatements Nepovinný parametr. Příkaz(y) pro zpracování chyb, ke kterým došlo v přidruženém Try bloku. Může to být složený příkaz.
Exit Try Nepovinný parametr. Klíčové slovo, které přeruší Try...Catch...Finally strukturu. Provádění pokračuje s kódem bezprostředně za End Try příkazem . Příkaz Finally se bude stále provádět. Není povoleno v Finally blocích.
Finally Nepovinný parametr. Blok Finally se vždy spustí, když provádění opustí jakoukoli část Try...Catch příkazu.
finallyStatements Nepovinný parametr. Příkazy, které se spustí po zpracování všech ostatních 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 ke konkrétní výjimce, umístěte kód do bloku a použijte blok k zachování řízení a zpracování výjimky, pokud Try Catch k ní dojde.

Příkaz Try…Catch se skládá z bloku Try následované jednou nebo více klauzulemi, které určují obslužné rutiny Catch pro různé výjimky. Když je v bloku vyvolána Try výjimka, Visual Basic Catch příkaz, který výjimku zpracuje. Pokud není nalezen odpovídající příkaz, Visual Basic prozkoumá metodu, která volala aktuální metodu, a tak dále v Catch zásobníku volání. Pokud není nalezen žádný blok, Visual Basic uživateli zprávu o neošetřené výjimce a zastaví Catch provádění programu.

V příkazu můžete použít Catch více než Try…Catch jeden příkaz. Pokud to chcete provést, pořadí Catch klauzulí je důležité, protože jsou prozkoumány v pořadí. Zachyťte konkrétnější výjimky před méně specifickými výjimkami.

Následující podmínky příkazu jsou nejméně specifické a zachytí všechny Catch výjimky, které jsou odvozeny z Exception třídy. Obvykle byste měli jednu z těchto variací použít jako poslední blok ve struktuře po zachycení všech konkrétních Catch Try...Catch...Finally výjimek, které očekáváte. Tok řízení se nikdy nemůže dostat Catch k bloku, který následuje po jedné z těchto variací.

  • typeje Exception , například:Catch ex As Exception

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

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

Místní proměnné z Try bloku nejsou v bloku k Catch dispozici, protože jsou to 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 technologie IntelliSense. Ve Správci fragmentů kódu rozbalte vzory kódu – If, For Each, Try Catch, Property atd. a 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é je nutné spustit před ukončením Try struktury, použijte Finally blok . Řízení se předá Finally bloku těsně před jeho průchodem ze Try…Catch struktury. To platí i v případě, že dojde k výjimce kdekoli uvnitř Try struktury.

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

Kód v bloku Finally se spustí i v případě, že váš kód narazí na příkaz v bloku nebo Return Try Catch . Řízení se nepředá z Try bloku Catch nebo do odpovídajícího bloku v následujících Finally případech:

Není platné explicitně přenést provádění do Finally bloku. Přenos provádění mimo Finally blok není platný, s výjimkou výjimky.

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

Tip

Pokud není třeba zachytit konkrétní výjimky, příkaz se chová jako blok a zaručuje vyřazení prostředků bez ohledu na způsob ukončení Using Try…Finally bloku. To platí i při neošetřené výjimce. Další informace najdete v tématu Using – příkaz.

Argument výjimky

Argument Catch exception bloku je instance třídy Exception nebo třídy, která je odvozena z 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. Například vlastnost obsahuje seznam zvaných metod, které vedly k výjimce, což vám pomůže zjistit, kde v kódu StackTrace došlo k chybě. Message vrátí zprávu, která popisuje výjimku. HelpLink vrátí odkaz na přidružený soubor nápovědy. InnerException vrátí objekt , který způsobil aktuální výjimku, nebo vrátí , Exception pokud neexistuje žádný původní objekt Nothing Exception .

Co je třeba vzít v úvahu při použití... Catch – příkaz

Příkaz slouží Try…Catch pouze k signálu výskytu neobvyklých nebo neočekávaných událostí programu. Mezi důvody patří:

  • Zachytání výjimek za běhu vytváří další režii a je pravděpodobně pomalejší než předběžná kontrola, aby se zabránilo výjimce.

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

  • Zpracování výjimek činí program složitějším.

Příkaz není vždy potřeba ke kontrole podmínky, Try…Catch která pravděpodobně nastane. Následující příklad zkontroluje, jestli soubor existuje, než se ho pokusíte otevřít. To snižuje potřebu zachycení výjimky vyvolané OpenText metodou .

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

Zajistěte, aby kód v blocích mohl správně hlásit výjimky uživatelům, ať už prostřednictvím protokolování bezpečného pro přístup z více Catch vláken, nebo vhodných zpráv. Jinak mohou výjimky zůstat neznámé.

Asynchronní metody

Pokud označíte metodu modifikátorem Async, můžete v metodě použít operátor Await. Příkaz s Await operátorem pozastaví provádění metody, dokud se nedokončí čekající úloha. Úkol představuje probíhající práci. Po dokončení úlohy přidružené k Await operátoru se provádění obnoví ve stejné metodě. Další informace najdete v tématu Řízení Flow v programech s modifikátorem Async.

Úloha vrácená asynchronní metodou může končila ve chybovém stavu, což značí, že byla dokončena kvůli neošetřené výjimce. Úloha může také končít ve zrušeném stavu, což má za výsledek vyvolání OperationCanceledException z výrazu await. Pokud chcete zachytit některý z typů výjimek, umístěte výraz přidružený k úloze do bloku a zachyťte Await Try výjimku v bloku Catch . Příklad je k dispozici dále v tomto tématu.

Úloha může být ve chybovém stavu, protože za selhání bylo zodpovědné více výjimek. Úloha může být například výsledkem volání Task.WhenAll metody . Když čekáte na takovou úlohu, zachycená výjimka je pouze jednou z výjimek a nemůžete předpovědět, která výjimka bude zachycena. Příklad je k dispozici dále v tomto tématu.

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

Iterátory

Funkce iterátoru Get nebo přistupující objekt provádí vlastní iteraci kolekce. Iterátor používá příkaz Yield k vrácení jednotlivých prvků kolekce. Funkci iterátoru voláte pomocí funkce For Each... Next – příkaz.

Příkaz Yield může být uvnitř Try bloku. Blok, Try který obsahuje příkaz , může mít bloky a může mít Yield Catch Finally blok. Příklad najdete v části Try Blocks in Visual Basic v části Iterátory.

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

Pokud tělo (mimo funkci iterátoru) vyvolá výjimku, blok ve funkci iterátoru není spuštěn, ale je proveden blok ve funkci For Each Catch Finally iterátoru. Blok Catch uvnitř funkce iterátoru zachycuje pouze výjimky, ke kterým dochází uvnitř funkce iterátoru.

Situace částečné důvěryhodnosti

V situacích s částečnou důvěryhodností, jako je například aplikace hostovaná ve sdílené síťové sdílené síti, nezachytí výjimky zabezpečení, ke kterým došlo před vyvoláním metody, která Try...Catch...Finally obsahuje volání. Když ji v následujícím příkladu dáte do sdílené složky serveru a spustíte z ní, dojde k chybě System.Security.SecurityException: Požadavek se nezdařil. Další informace o výjimce zabezpečení najdete v třídě SecurityException .

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

V takové situaci částečné důvěryhodnosti musíte příkaz Process.Start umístit do samostatného Sub souboru . Počáteční volání metody Sub selže. To umožňuje zachytit před spuštění , který obsahuje a Try...Catch Sub Process.Start vytvořena výjimka zabezpečení.

Příklady

Struktura try... Chytit... Konečně

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

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

Výjimka v metodě s názvem z bloku Try

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

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

Public Sub RunSample()
    Try
        CreateException()
    Catch ex As System.IO.IOException
        ' Code that reacts to IOException.
    Catch ex As NullReferenceException
        MessageBox.Show("NullReferenceException: " & ex.Message)
        MessageBox.Show("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 použití příkazu k Catch When filtrování podmíněného výrazu. Pokud se podmíněný výraz vyhodnotí jako True , kód v bloku se Catch 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é příkazy Try

Následující příklad obsahuje Try…Catch příkaz , který je obsažen v bloku Try . Vnitřní blok Catch vyvolá výjimku, která má vlastnost InnerException 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 ukazuje zpracování výjimek pro asynchronní metody. Chcete-li zachytit výjimku, která se vztahuje na asynchronní úlohu, je výraz v bloku volajícího a výjimka Await Try je zachycena v Catch bloku.

Odkomentování Throw New Exception řádku v příkladu pro předvedení zpracování výjimek. Výjimka je zachycena v bloku, vlastnost úlohy je nastavena na a vlastnost úkolu je Catch IsFaulted True Exception.InnerException nastavena na výjimku.

Odkomentování Throw New OperationCancelledException řádku, aby bylo předvedení, co se stane, když zrušíte asynchronní proces. Výjimka je zachycena v bloku a vlastnost úlohy je Catch IsCanceled nastavena na True . Za některých podmínek, které se na tento příklad nevztahují, je ale nastavená na a IsFaulted True je IsCanceled nastavená na 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

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

Následující příklad znázorňuje zpracování výjimek, kdy může více úloh vést k více výjimce. Blok Try obsahuje výraz pro Await vrácenou Task.WhenAll úlohu. Úloha je dokončena po dokončení tří úkolů, na Task.WhenAll které se aplikace použije.

Každý z těchto tří úkolů způsobí výjimku. Blok Catch iteruje výjimkami, které se nacházejí ve vlastnosti vrácené Exception.InnerExceptions Task.WhenAll úlohy.

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é