Partilhar via


Try...Catch...Finally Instrução (Visual Basic)

Fornece uma maneira de lidar com alguns ou todos os erros possíveis que podem ocorrer em um determinado bloco de código, enquanto ainda executa o código.

Sintaxe

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

Partes

Termo Definição
tryStatements Opcional. Instrução(ões) onde um erro pode ocorrer. Pode ser uma instrução composta.
Catch Opcional. Vários Catch blocos permitidos. Se ocorrer uma exceção durante o processamento do Try bloco, cada Catch instrução será examinada em ordem textual para determinar se ela manipula a exceção, representando exception a exceção que foi lançada.
exception Opcional. Qualquer nome de variável. O valor inicial de exception é o valor do erro lançado. Usado com Catch para especificar o erro detetado. Se omitida, a Catch declaração captura qualquer exceção.
type Opcional. Especifica o tipo de filtro de classe. Se o valor de é do tipo especificado por type ou de um tipo derivado, o identificador torna-se vinculado ao objeto de exception exceção.
When Opcional. Uma Catch declaração com uma When cláusula captura exceções somente quando expression avaliada como True. Uma When cláusula só é aplicada depois de verificado o tipo de exceção e expression pode referir-se ao identificador que representa a exceção.
expression Opcional. Deve ser implicitamente convertível em Boolean. Qualquer expressão que descreva um filtro genérico. Normalmente usado para filtrar por número de erro. Usado com When palavra-chave para especificar as circunstâncias em que o erro é detetado.
catchStatements Opcional. Instrução(ões) para lidar com erros que ocorrem no bloco associado Try . Pode ser uma instrução composta.
Exit Try Opcional. Palavra-chave que rompe a Try...Catch...Finally estrutura. A execução é retomada com o código imediatamente após a End Try instrução. A Finally instrução ainda será executada. Não permitido em Finally blocos.
Finally Opcional. Um Finally bloco é sempre executado quando a execução deixa qualquer parte da Try...Catch instrução.
finallyStatements Opcional. Instrução(ões) que são executadas após o processamento de todos os outros erros terem ocorrido.
End Try Encerra a Try...Catch...Finally estrutura.

Observações

Se você espera que uma exceção específica possa ocorrer durante uma seção específica do código, coloque o código em um Try bloco e use um Catch bloco para manter o controle e manipular a exceção se ela ocorrer.

Uma Try…Catch instrução consiste em um Try bloco seguido por uma ou mais Catch cláusulas, que especificam manipuladores para várias exceções. Quando uma exceção é lançada em um Try bloco, o Visual Basic procura a Catch instrução que manipula a exceção. Se uma instrução correspondente Catch não for encontrada, o Visual Basic examinará o método que chamou o método atual e assim por diante na pilha de chamadas. Se nenhum Catch bloco for encontrado, o Visual Basic exibirá uma mensagem de exceção sem tratamento para o usuário e interromperá a execução do programa.

Você pode usar mais de uma Catch instrução em uma Try…Catch instrução. Se o fizer, a ordem das cláusulas é significativa porque são examinadas Catch por ordem. Catch as exceções mais específicas antes das menos específicas.

As condições da instrução a seguir Catch são as menos específicas e capturarão todas as exceções derivadas da Exception classe. Normalmente, você deve usar uma dessas variações como o último Catch bloco na Try...Catch...Finally estrutura, depois de capturar todas as exceções específicas que você espera. O fluxo de controle nunca pode atingir um bloco que siga qualquer uma Catch dessas variações.

  • O type é Exception, por exemplo: Catch ex As Exception

  • A instrução não exception tem variável, por exemplo: Catch

Quando uma Try…Catch…Finally instrução é aninhada em outro Try bloco, o Visual Basic primeiro examina cada Catch instrução no bloco mais Try interno. Se nenhuma instrução correspondente Catch for encontrada, a pesquisa prosseguirá para as Catch instruções do bloco externo Try…Catch…Finally .

As variáveis locais de um Try bloco não estão disponíveis em um Catch bloco porque são blocos separados. Se você quiser usar uma variável em mais de um bloco, declare a variável fora da Try...Catch...Finally estrutura.

Gorjeta

A Try…Catch…Finally instrução está disponível como um trecho de código do IntelliSense. No Gerenciador de trechos de código, expanda Padrões de código - Se, para cada um, TryCatch, Propriedade, etc e, em seguida, Tratamento de erros (exceções). Para obter mais informações, consulte Trechos de código.

bloco Finally

Se você tiver uma ou mais instruções que devem ser executadas antes de sair da Try estrutura, use um Finally bloco. O controle passa para o Finally bloco pouco antes de ele sair da Try…Catch estrutura. Isso é verdade mesmo se uma exceção ocorrer em qualquer lugar dentro da Try estrutura.

Um Finally bloco é útil para executar qualquer código que deva ser executado, mesmo que haja uma exceção. O controle é passado para o Finally bloco independentemente de como o Try...Catch bloco sai.

O código em um Finally bloco é executado mesmo se o código encontrar uma Return instrução em um Try ou Catch bloco. O controlo não passa de um Try ou Catch bloco para o bloco correspondente Finally nos seguintes casos:

Não é válido transferir explicitamente a execução para um Finally bloco. A transferência da execução para fora de um Finally bloco não é válida, exceto através de uma exceção.

Se uma Try instrução não contiver pelo menos um Catch bloco, ela deve conter um Finally bloco.

Gorjeta

Se você não tiver que pegar exceções específicas, a Using declaração se comporta como um Try…Finally bloco e garante o descarte dos recursos, independentemente de como você sair do bloco. Isso é verdade mesmo com uma exceção não tratada. Para obter mais informações, consulte Usando instrução.

Argumento de exceção

O Catch argumento block exception é uma instância da Exception classe ou uma classe que deriva da Exception classe. A Exception instância de classe corresponde ao erro que ocorreu no Try bloco .

As propriedades do Exception objeto ajudam a identificar a causa e o local de uma exceção. Por exemplo, a StackTrace propriedade lista os métodos chamados que levaram à exceção, ajudando você a encontrar onde o erro ocorreu no código. Message Retorna uma mensagem que descreve a exceção. HelpLink retorna um link para um arquivo de Ajuda associado. InnerException retorna o Exception objeto que causou a exceção atual ou retorna Nothing se não houver nenhum original Exception.

Considerações ao usar uma Try…Catch instrução

Use uma Try…Catch instrução apenas para sinalizar a ocorrência de eventos incomuns ou imprevistos do programa. As razões para isso incluem o seguinte:

  • CatchAs exceções de ing em tempo de execução criam sobrecarga adicional e provavelmente serão mais lentas do que a pré-verificação para evitar exceções.

  • Se um Catch bloco não for tratado corretamente, a exceção pode não ser relatada corretamente aos usuários.

  • O tratamento de exceções torna um programa mais complexo.

Nem sempre é necessária uma Try…Catch declaração para verificar a existência de uma condição suscetível de ocorrer. O exemplo a seguir verifica se um arquivo existe antes de tentar abri-lo. Isso reduz a necessidade de capturar uma exceção lançada pelo OpenText método.

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

Certifique-se de que o código em Catch blocos possa relatar adequadamente as exceções aos usuários, seja por meio de registro seguro de threads ou mensagens apropriadas. Caso contrário, as exceções podem permanecer desconhecidas.

Métodos assíncronos

Se você marcar um método com o modificador Async , poderá usar o operador Await no método. Uma instrução com o operador suspende Await a execução do método até que a tarefa aguardada seja concluída. A tarefa representa um trabalho contínuo. Quando a tarefa associada ao Await operador é concluída, a execução é retomada no mesmo método. Para obter mais informações, consulte Fluxo de controle em programas assíncronos.

Uma tarefa retornada por um método Assíncrono pode terminar em um estado com falha, indicando que foi concluída devido a uma exceção não tratada. Uma tarefa também pode terminar em um estado cancelado, o que resulta em um OperationCanceledException ser expulso da expressão aguardar. Para capturar qualquer tipo de exceção, coloque a Await expressão associada à tarefa em um Try bloco e capture a exceção no Catch bloco . Um exemplo é fornecido mais adiante neste tópico.

Uma tarefa pode estar em um estado de falha porque várias exceções foram responsáveis por sua falha. Por exemplo, a tarefa pode ser o resultado de uma chamada para Task.WhenAll. Quando você aguarda tal tarefa, a exceção capturada é apenas uma das exceções, e você não pode prever qual exceção será capturada. Um exemplo é fornecido mais adiante neste tópico.

Uma Await expressão não pode estar dentro de um Catch bloco ou Finally bloco.

Iteradores

Uma função iteradora ou Get acessador executa uma iteração personalizada sobre uma coleção. Um iterador usa uma instrução Yield para retornar cada elemento da coleção, um de cada vez. Você chama uma função de iterador usando um For Each... Próxima declaração.

Uma Yield instrução pode estar dentro de um Try bloco. Um Try bloco que contém uma Yield instrução pode ter Catch blocos e pode ter um Finally bloco. Para obter um exemplo, consulte Try Blocos.

Uma Yield instrução não pode estar dentro de um Catch bloco ou de um Finally bloco.

Se o For Each corpo (fora da função iterador) lançar uma exceção, um Catch bloco na função iterador não será executado, mas um Finally bloco na função iterador será executado. Um Catch bloco dentro de uma função iteradora captura apenas exceções que ocorrem dentro da função iterador.

Situações de confiança parcial

Em situações de confiança parcial, como um aplicativo hospedado em um compartilhamento de rede, Try...Catch...Finally não captura exceções de segurança que ocorrem antes que o método que contém a chamada seja invocado. O exemplo a seguir, quando você o coloca em um compartilhamento de servidor e executa a partir daí, produz o erro "System.Security.SecurityException: Falha na solicitação". Para obter mais informações sobre exceções de segurança, consulte a SecurityException classe.

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

Em tal situação de confiança parcial, você tem que colocar a Process.Start declaração em separado Sub. A chamada inicial para o Sub irá falhar. Isso permite Try...Catch capturá-lo antes que o Sub que contém Process.Start seja iniciado e a exceção de segurança produzida.

Exemplos

A estrutura do Try...Catch...Finally

O exemplo a seguir ilustra a estrutura da Try...Catch...Finally instrução.

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

Exceção em um método chamado de um Try bloco

No exemplo a seguir, o CreateException método lança um NullReferenceExceptionarquivo . O código que gera a exceção não está em um Try bloco. Portanto, o CreateException método não manipula a exceção. O RunSample método manipula a exceção porque a chamada para o CreateException método está em um Try bloco.

O exemplo inclui Catch instruções para vários tipos de exceções, ordenadas do mais específico para o mais geral.

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 instrução When

O exemplo a seguir mostra como usar uma Catch When instrução para filtrar uma expressão condicional. Se a expressão condicional for avaliada como True, o Catch código no bloco será executado.

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

Instruções aninhadas Try

O exemplo a seguir tem uma Try…Catch instrução contida em um Try bloco . O bloco interno Catch lança uma exceção que tem sua InnerException propriedade definida como a exceção original. O bloco externo Catch relata sua própria exceção e a exceção interna.

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

Tratamento de exceções para métodos assíncronos

O exemplo a seguir ilustra o tratamento de exceções para métodos assíncronos. Para capturar uma exceção que se aplica a uma tarefa assíncrona, a Await expressão está em um Try bloco do chamador e a exceção é capturada Catch no bloco .

Descomente a linha no exemplo para demonstrar o Throw New Exception tratamento de exceções. A exceção é capturada Catch no bloco , a propriedade da IsFaulted tarefa é definida como True, e a propriedade da Exception.InnerException tarefa é definida como a exceção.

Descomente a linha para demonstrar o que acontece quando você cancela um processo assíncrono Throw New OperationCancelledException . A exceção é capturada Catch no bloco e a propriedade da IsCanceled tarefa é definida como True. No entanto, sob algumas condições que não se aplicam a este exemplo, IsFaulted está definido como True e IsCanceled está definido como 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

Tratamento de várias exceções em métodos assíncronos

O exemplo a seguir ilustra o tratamento de exceções em que várias tarefas podem resultar em várias exceções. O Try bloco tem a Await expressão para a tarefa que Task.WhenAll retornou. A tarefa é concluída quando as três tarefas às quais Task.WhenAll é aplicado estão concluídas.

Cada uma das três tarefas causa uma exceção. O Catch bloco itera através das exceções, que são encontradas na Exception.InnerExceptions propriedade da tarefa que Task.WhenAll retornou.

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

Consulte também