2009-09-04 15 views
17

¿Por qué querría salir de un Error Handler (después de la manipulación) con un Sub de salida en lugar de simplemente dejarlo ir al End Sub?Error Handler - Exit Sub vs. End Sub

Estoy seguro de que es simple. Simplemente no entiendo. Gracias por cualquier ayuda.

Ejemplo:

Public Sub SubA() 
On Error Goto ProcError 

    ''# other code 
    MsgBox FuncA() 

ProcExit: 
    Exit Sub 

ProcError: 
    MsgBox Err.Description 
    Resume ProcExit 
End Sub 

Respuesta

22

Su etiqueta ProcExit es su lugar donde libera todos los recursos, ya sea que haya ocurrido un error o no. Por ejemplo:

Public Sub SubA() 
    On Error Goto ProcError 

    Connection.Open 
    Open File for Writing 
    SomePreciousResource.GrabIt 

ProcExit: 
    Connection.Close 
    Connection = Nothing 
    Close File 
    SomePreciousResource.Release 

    Exit Sub 

ProcError: 
    MsgBox Err.Description 
    Resume ProcExit 
End Sub 
+1

+1. Y, obviamente, si no necesita cerrar o liberar ningún recurso, no es necesario y puede pasar al End Sub. – MarkJ

+0

@MarkJ: Eso probablemente sea correcto, pero me sentiría incómodo con eso. Si el error ha sido realmente "manejado", preferiría reanudar a ProcExit incluso si se sigue inmediatamente con Exit Sub. – AnthonyWJones

+8

¿Esto no causaría un bucle infinito si algo debajo de 'ProcExit' genera un error? –

1

Normalmente, si usted tiene conexiones de bases de datos u otros objetos declararon que, tanto si se utilizan de forma segura o creado antes de su excepción, tendrá que ser limpiado (se desechará), entonces la devolución de su error El manejo del código de regreso al punto de entrada ProcExit le permitirá hacer su recolección de basura en ambos casos.

Si se sale de su procedimiento al caer en la salida Sub, puede correr el riesgo de tener una acumulación de objetos instanciados que están sentados en la memoria de su programa.

+4

Mala selección de palabras. "Haz tu recolección de basura" y "sentado en la memoria de tu programa". Esto podría alentar religiosamente a establecer todas las referencias de objetos locales a Nothing al final de la rutina. De hecho, VB6 recogerá automáticamente los objetos y la memoria tan pronto como el recuento de referencias pase a cero. Si estaban en variables locales, esto sucede en la salida Sub. Solo debe preocuparse en relativamente pocos casos, cuando los recursos especiales deben liberarse explícitamente o cuando se necesita restaurar algún otro estado (por ejemplo, cambiar el puntero del mouse desde el reloj de arena). – MarkJ

+0

Punto justo. Mejor retoque mi VB6, supongo. Últimamente, se ha enfocado demasiado en los lenguajes divertidos modernos orientados a objetos ... –

+0

Aún puede necesitar "limpiar", más allá de simplemente eliminar las referencias de objetos al salir de su alcance. Es posible que tenga una referencia a un servidor fuera de proceso que requiere una solicitud de cierre explícita (por ejemplo, Excel puede estar esperando una llamada Salir). O tal vez desee liberar una referencia declarada fuera del alcance propio del procedimiento al salir. – Bob77