Instrucción Try...Catch...Finally (Visual Basic)
Proporciona una manera de controlar algunos o todos los errores posibles que pueden producirse en un bloque de código determinado, mientras se sigue ejecutando código.
Sintaxis
Try
[ tryStatements ]
[ Exit Try ]
[ Catch [ exception [ As type ] ] [ When expression ]
[ catchStatements ]
[ Exit Try ] ]
[ Catch ... ]
[ Finally
[ finallyStatements ] ]
End Try
Partes
| Término | Definición |
|---|---|
tryStatements |
Opcional. Instrucciones en las que se puede producir un error. Puede ser una instrucción compuesta. |
Catch |
Opcional. Se Catch permiten varios bloques. Si se produce una excepción al procesar el bloque, cada instrucción se examina en orden textual para determinar si controla la excepción, representando la excepción que se Try Catch ha exception producido. |
exception |
Opcional. Cualquier nombre de variable. El valor inicial de exception es el valor del error producido. Se usa Catch con para especificar el error capturado. Si se omite, la Catch instrucción detecta cualquier excepción. |
type |
Opcional. Especifica el tipo de filtro de clase. Si el valor de es del tipo especificado por o de un tipo derivado, el identificador se enlaza exception type al objeto de excepción. |
When |
Opcional. Una Catch instrucción con una cláusula detecta When excepciones solo cuando se evalúa como expression True . Una cláusula solo se aplica después de comprobar el tipo de excepción y puede hacer referencia When al identificador que representa la expression excepción. |
expression |
Opcional. Debe poder convertirse implícitamente en Boolean . Cualquier expresión que describa un filtro genérico. Normalmente se usa para filtrar por número de error. Se usa con When la palabra clave para especificar las circunstancias en las que se detecta el error. |
catchStatements |
Opcional. Instrucciones para controlar los errores que se producen en el bloque Try asociado. Puede ser una instrucción compuesta. |
Exit Try |
Opcional. Palabra clave que se interrumpe en la Try...Catch...Finally estructura. La ejecución se reanuda con el código inmediatamente después de la End Try instrucción . La Finally instrucción todavía se ejecutará. No se permite en Finally bloques. |
Finally |
Opcional. Un Finally bloque siempre se ejecuta cuando la ejecución sale de cualquier parte de la Try...Catch instrucción. |
finallyStatements |
Opcional. Instrucciones que se ejecutan después de que se haya producido el resto del procesamiento de errores. |
End Try |
Finaliza la Try...Catch...Finally estructura . |
Observaciones
Si espera que se produzca una excepción determinada durante una sección determinada del código, coloque el código en un bloque y use un bloque para conservar el control y controlar la excepción si Try Catch se produce.
Una Try…Catch instrucción consta de un bloque seguido de una o varias Try Catch cláusulas, que especifican controladores para varias excepciones. Cuando se produce una excepción en un Try bloque, Visual Basic busca la Catch instrucción que controla la excepción. Si no se encuentra una instrucción de coincidencia, Visual Basic el método que llamó al método actual, y así sucesivamente Catch en la pila de llamadas. Si no se encuentra ningún bloque, Visual Basic un mensaje de excepción no controlada al usuario y Catch detiene la ejecución del programa.
Puede usar más de una Catch instrucción en una instrucción Try…Catch . Si lo hace, el orden de las Catch cláusulas es significativo porque se examinan en orden. Detectar las excepciones más específicas antes que las menos específicas.
Las siguientes Catch condiciones de instrucción son las menos específicas y detectarán todas las excepciones que derivan de la Exception clase . Normalmente, debe usar una de estas variaciones como último bloque de la estructura, después de detectar todas las Catch Try...Catch...Finally excepciones específicas que espera. El flujo de control nunca puede alcanzar Catch un bloque que siga cualquiera de estas variaciones.
es
typeException, por ejemplo:Catch ex As ExceptionLa instrucción no tiene
exceptionninguna variable, por ejemplo:Catch
Cuando una instrucción está anidada en otro bloque, Visual Basic primero Try…Catch…Finally examina cada instrucción del bloque más Try Catch Try interno. Si no se encuentra ninguna instrucción correspondiente, la búsqueda continúa con Catch las instrucciones del bloque Catch Try…Catch…Finally externo.
Las variables locales de Try un bloque no están disponibles en un bloque porque son Catch bloques independientes. Si desea usar una variable en más de un bloque, declare la variable fuera de la Try...Catch...Finally estructura .
Sugerencia
La Try…Catch…Finally instrucción está disponible como fragmento de código de IntelliSense. En el Administrador de fragmentos de código, expanda Patrones de código: If, For Each, Try Catch, Property, etc. y, a continuación, Control de errores (excepciones). Para obtener más información, vea Fragmentos de código.
Bloque Finally
Si tiene una o varias instrucciones que deben ejecutarse antes de salir de la Try estructura, use un Finally bloque . El control pasa al Finally bloque justo antes de salir de la Try…Catch estructura. Esto es así incluso si se produce una excepción en cualquier parte dentro de la Try estructura .
Un Finally bloque es útil para ejecutar cualquier código que se deba ejecutar incluso si hay una excepción. El control se pasa al Finally bloque independientemente de cómo Try...Catch se cierre el bloque.
El código de un bloque se ejecuta incluso si el código encuentra Finally una instrucción en un bloque o Return Try Catch . El control no pasa de un Try bloque o al bloque correspondiente en los Catch Finally casos siguientes:
Se encuentra una instrucción End en el bloque o
TryCatch.Se StackOverflowException produce una excepción en el bloque
TryoCatch.
No es válido transferir explícitamente la ejecución a un Finally bloque. La transferencia de la ejecución fuera Finally de un bloque no es válida, excepto a través de una excepción.
Si una Try instrucción no contiene al menos un Catch bloque, debe contener un bloque Finally .
Sugerencia
Si no tiene que detectar excepciones específicas, la instrucción se comporta como un bloque y garantiza la eliminación de los recursos, independientemente de cómo salga Using Try…Finally del bloque. Esto es así incluso con una excepción no controlada. Para obtener más información, vea Using (Instrucción).
Argumento de excepción
El Catch argumento block es una instancia de la clase o una clase que deriva de la clase exception Exception Exception . La Exception instancia de clase corresponde al error que se produjo en el bloque Try .
Las propiedades del objeto Exception ayudan a identificar la causa y la ubicación de una excepción. Por ejemplo, la propiedad enumera los métodos llamados que provocaron la excepción, lo que le ayuda a encontrar dónde se produjo StackTrace el error en el código. Message devuelve un mensaje que describe la excepción. HelpLink devuelve un vínculo a un archivo de Ayuda asociado. InnerException devuelve el Exception objeto que produjo la excepción actual o devuelve Nothing si no hay ningún objeto Exception original.
Consideraciones al usar un try... Instrucción Catch
Use una instrucción solo para indicar la aparición de eventos de programa inusuales Try…Catch o imprevistos. Entre los motivos de esto se incluyen los siguientes:
Detectar excepciones en tiempo de ejecución crea una sobrecarga adicional y es probable que sea más lenta que la comprobación previa para evitar excepciones.
Si un bloque no se controla correctamente, es posible que la excepción no
Catchse notime correctamente a los usuarios.El control de excepciones hace que un programa sea más complejo.
No siempre necesita una instrucción para comprobar si hay una Try…Catch condición que es probable que se produzca. En el ejemplo siguiente se comprueba si existe un archivo antes de intentar abrirlo. Esto reduce la necesidad de detectar una excepción producida por el 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
Asegúrese de que el código de los bloques puede notificar correctamente las excepciones a los usuarios, ya sea mediante el registro seguro para Catch subprocesos o los mensajes adecuados. De lo contrario, es posible que las excepciones sigan siendo desconocidas.
Métodos asincrónicos
Si marca un método con el modificador Async, puede usar el operador Await en el método . Una instrucción con el Await operador suspende la ejecución del método hasta que se complete la tarea esperada. La tarea representa el trabajo en curso. Cuando finaliza la tarea asociada al Await operador , la ejecución se reanuda en el mismo método. Para obtener más información, vea Control Flow en Programas asincrónicos.
Una tarea devuelta por un método asincrónico puede terminar en un estado de error, lo que indica que se completó debido a una excepción no controlada. Una tarea también puede terminar en un estado cancelado, lo que da lugar a una salida OperationCanceledException de la expresión await. Para detectar cualquier tipo de excepción, coloque la expresión asociada a la tarea en un bloque y la excepción Await Try en el bloque Catch . Más adelante en este tema se proporciona un ejemplo.
Una tarea puede estar en un estado de error porque varias excepciones eran responsables de su error. Por ejemplo, la tarea podría ser el resultado de una llamada a Task.WhenAll. Cuando espera una tarea de este tipo, la excepción detectada es solo una de las excepciones y no puede predecir qué excepción se va a capturar. Más adelante en este tema se proporciona un ejemplo.
Una Await expresión no puede estar dentro de un bloque o Catch Finally bloque.
Iterators
Una función de iterador o Get un accessor realiza una iteración personalizada en una colección. Un iterador usa una instrucción Yield para devolver cada elemento de la colección de uno en uno. Para llamar a una función de iterador, use for Each... Instrucción Next.
Una Yield instrucción puede estar dentro de un Try bloque. Un Try bloque que contiene una instrucción puede tener Yield Catch bloques y puede tener un bloque Finally . Consulte la sección "Try Blocks in Visual Basic" (Probar bloques en Visual Basic) de Iteradores para obtener un ejemplo.
Una Yield instrucción no puede estar dentro de un bloque o un Catch Finally bloque.
Si el cuerpo (fuera de la función de iterador) produce una excepción, no se ejecuta un bloque de la función iterador, pero se ejecuta un bloque de la función For Each Catch de Finally iterador. Un bloque dentro de una función de iterador detecta solo las Catch excepciones que se producen dentro de la función de iterador.
Situaciones de confianza parcial
En situaciones de confianza parcial, como una aplicación hospedada en un recurso compartido de red, no detecta las excepciones de seguridad que se producen antes de invocar el método que Try...Catch...Finally contiene la llamada. En el ejemplo siguiente, cuando se coloca en un recurso compartido de servidor y se ejecuta desde allí, se genera el error "System.Security.SecurityException: Request Failed". Para obtener más información sobre las excepciones de seguridad, vea la SecurityException clase .
Try
Process.Start("http://www.microsoft.com")
Catch ex As Exception
MsgBox("Can't load Web page" & vbCrLf & ex.Message)
End Try
En una situación de confianza parcial, tiene que colocar la Process.Start instrucción en un Sub independiente. Se producirá un error en la llamada Sub inicial a . Esto permite Try...Catch detectarlo antes de que Sub se inicia el que contiene y se produce la Process.Start excepción de seguridad.
Ejemplos
La estructura de Try... Atrapar... Finalmente
En el ejemplo siguiente se muestra la estructura de la Try...Catch...Finally instrucción .
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
Excepción en un método llamado desde un bloque Try
En el ejemplo siguiente, CreateException el método produce una NullReferenceException excepción . El código que genera la excepción no está en un Try bloque. Por lo tanto, CreateException el método no controla la excepción. El RunSample método controla la excepción porque la llamada al método está en un bloque CreateException Try .
En el ejemplo Catch se incluyen instrucciones para varios tipos de excepciones, ordenadas de la más específica a la más general.
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
Instrucción Catch When
En el ejemplo siguiente se muestra cómo usar una Catch When instrucción para filtrar por una expresión condicional. Si la expresión condicional se evalúa como True , se ejecuta el código del bloque Catch .
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
Instrucciones Try anidadas
En el ejemplo siguiente se Try…Catch incluye una instrucción que se encuentra en un bloque Try . El bloque Catch interno produce una excepción que tiene su InnerException propiedad establecida en la excepción original. El bloque Catch externo notifica su propia excepción y la excepción 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
Control de excepciones para métodos asincrónicos
En el ejemplo siguiente se muestra el control de excepciones de los métodos asincrónicos. Para detectar una excepción que se aplica a una tarea asincrónica, la expresión está en un bloque del autor de la llamada y la excepción se Await detecta en el bloque Try Catch .
Quite la marca de comentario de la línea Throw New Exception en el ejemplo para demostrar el control de excepciones. La excepción se detecta en el bloque , la propiedad de la tarea se establece en y la propiedad de la tarea se Catch IsFaulted establece en la True Exception.InnerException excepción.
Quite la marca de comentario de la línea Throw New OperationCancelledException para ver lo que pasa cuando se cancela un proceso asincrónico. La excepción se detecta en Catch el bloque y la propiedad de la tarea se establece en IsCanceled True . Sin embargo, en algunas condiciones que no se aplican a este ejemplo, se IsFaulted establece en y se establece en True IsCanceled 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
Control de varias excepciones en métodos asincrónicos
En el ejemplo siguiente se muestra el control de excepciones en el que varias tareas pueden producir varias excepciones. El Try bloque tiene la expresión para la tarea Await Task.WhenAll devuelta. La tarea se completa cuando se completan las tres tareas a las Task.WhenAll que se aplica.
Cada una de las tres tareas produce una excepción. El Catch bloque recorre en iteración las excepciones, que se encuentran en la propiedad de la tarea Exception.InnerExceptions Task.WhenAll devuelta.
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