without try español ejemplos catch bloque c# .net vb.net exception-handling

c# - español - Will Try/Finally(sin la captura) burbuja de la excepción?



try catch finally c# ejemplos (2)

Estoy casi seguro de que la respuesta es SÍ. Si utilizo un bloque Try Finally pero no utilizo un bloque Catch, entonces las excepciones serán burbujas. ¿Correcto?

¿Alguna idea sobre la práctica en general?

Seth


¿Alguna idea sobre la práctica en general?

Sí. Ten cuidado Cuando su bloque finally se está ejecutando, es muy posible que se esté ejecutando porque se ha lanzado una excepción no controlada e inesperada . Eso significa que algo está roto , y algo completamente inesperado podría estar sucediendo.

En esa situación, podría decirse que no se debe ejecutar código en bloques finalmente. El código en el bloque finally podría construirse para suponer que los subsistemas de los que depende son saludables, cuando de hecho podrían estar profundamente rotos. El código en el bloque final podría empeorar las cosas.

Por ejemplo, a menudo veo este tipo de cosas:

DisableAccessToTheResource(); try { DoSomethingToTheResource(); } finally { EnableAccessToTheResource(); }

El autor de este código está pensando: "Estoy haciendo una mutación temporal al estado del mundo, necesito restaurar el estado a lo que era antes de que me llamaran". Pero pensemos sobre todas las formas en que esto podría salir mal.

Primero, el acceso al recurso ya podría ser deshabilitado por la persona que llama; en ese caso, este código lo vuelve a habilitar, posiblemente prematuramente.

En segundo lugar, si DoSomethingToTheResource arroja una excepción, ¿es lo correcto para habilitar el acceso al recurso? El código que administra el recurso se rompe inesperadamente . Este código dice, de hecho, "si el código de administración está roto, asegúrese de que otro código pueda llamar a ese código roto lo antes posible, para que también pueda fallar horriblemente ". Esto parece una mala idea.

En tercer lugar, si DoSomethingToTheResource arroja una excepción, ¿cómo sabemos que EnableAccessToTheResource no lanzará también una excepción? Independientemente de lo horrible que haya sido el uso del recurso, también podría afectar el código de limpieza, en cuyo caso la excepción original se perderá y el problema será más difícil de diagnosticar.

Tiendo a escribir código como este sin usar bloques try-finally:

bool wasDisabled = IsAccessDisabled(); if (!wasDisabled) DisableAccessToTheResource(); DoSomethingToTheResource(); if (!wasDisabled) EnableAccessToTheResource();

Ahora el estado no está mutado a menos que sea necesario. Ahora el estado de la persona que llama no está enredado. Y ahora, si DoSomethingToTheResource falla, no volvemos a habilitar el acceso. Suponemos que algo está profundamente roto y no corremos el riesgo de empeorar la situación tratando de seguir ejecutando el código. Deje que la persona que llama lidie con el problema, si pueden.

Entonces, ¿cuándo es una buena idea ejecutar un bloque finalmente? Primero, cuando se espera la excepción. Por ejemplo, puede esperar que un intento de bloquear un archivo falle, porque alguien más lo tiene bloqueado. En ese caso, tiene sentido detectar la excepción e informar al usuario. En ese caso, la incertidumbre sobre lo que se rompe se reduce; es poco probable que empeore las cosas al limpiar.

Segundo, cuando el recurso que está limpiando es un recurso escaso del sistema. Por ejemplo, tiene sentido cerrar un identificador de archivo en un bloque finally. (Un "uso" es, por supuesto, solo otra forma de escribir un bloque try-finally.) El contenido del archivo puede estar dañado, pero no hay nada que puedas hacer al respecto ahora. El identificador de archivo se cerrará eventualmente, por lo que podría ser más pronto que tarde.


Sí, absolutamente lo hará. Asumiendo que su bloqueo final no arroja una excepción, por supuesto, en cuyo caso eso efectivamente "reemplazará" al originalmente lanzado.