visual usar try mvc form como catch c# try-catch

c# - usar - try catch visual basic



¿El bloque C#"finally" SIEMPRE se ejecuta? (11)

De MSDN try-finally (referencia C #)

El bloque finally es útil para limpiar cualquier recurso asignado en el bloque try así como para ejecutar cualquier código que deba ejecutarse incluso si hay una excepción. El control siempre pasa al bloque finally independientemente de cómo salga el bloque try .

Posible duplicado:
¿Describirá el código en una instrucción Finally si devuelvo un valor en un bloque Try?

Considere el siguiente código código C #. ¿El bloque "finalmente" se ejecuta?

public void DoesThisExecute() { string ext = "xlsx"; string message = string.Empty; try { switch (ext) { case "xls": message = "Great choice!"; break; case "csv": message = "Better choice!"; break; case "exe": message = "Do not try to break me!"; break; default: message = "You will not win!"; return; } } catch (Exception) { // Handle an exception. } finally { MessageBox.Show(message); } }

Después de terminar de escribir esto, me di cuenta de que podría haberlo probado yo mismo en Visual Studio. Sin embargo, ¡no dude en responder!


De la especificación MSDN C # de la declaración try :

Las instrucciones de un bloque finally siempre se ejecutan cuando el control deja una instrucción try . Esto es así ya sea que la transferencia de control ocurra como resultado de la ejecución normal, como resultado de la ejecución de una goto break , continue , goto o return , o como resultado de la propagación de una excepción fuera de la instrucción try .

Source

Existen los casos donde el bloque finally no se ejecutará:

  1. Environment.FailFast
  2. Tipos de excepciones incautables
  3. Fallo de alimentación

El bloque finally se ejecutará, justo entre estas líneas:

message = "You will not win!"; return;


La respuesta correcta es Sí.

Intenta depurar tu programa y pon un punto de quiebre y mira como el control sigue llegando al bloque finally.


No es totalmente cierto que finally siempre se ejecutará. Ver esta respuesta de Haacked :

Dos posibilidades:

  • Exception
  • ExecutingEngineException

El bloque finally no se ejecutará cuando exista Exception ya que no hay espacio en la pila para ejecutar más código. Tampoco se llamará cuando exista ExecutingEngineException, lo cual es muy raro.

De hecho, para cualquier tipo de excepción asincrónica (como Exception , OutOfMemoryException , ThreadAbortException ) la ejecución de un bloque finally no está garantizada.

Sin embargo, estas excepciones son excepciones de las que generalmente no puede recuperarse y, en la mayoría de los casos, su proceso finalizará de todos modos.

De hecho, también existe al menos otro caso en el que finally no se ejecuta como describió Brian Rasmussen en una pregunta ahora eliminada :

El otro caso que conozco es si un finalizador arroja una excepción. En ese caso, el proceso finaliza inmediatamente también, y por lo tanto la garantía no se aplica.

El código a continuación ilustra el problema

static void Main(string[] args) { try { DisposableType d = new DisposableType(); d.Dispose(); d = null; GC.Collect(); GC.WaitForPendingFinalizers(); } catch { Console.WriteLine("catch"); } finally { Console.WriteLine("finally"); } } public class DisposableType : IDisposable { public void Dispose() { } ~DisposableType() { throw new NotImplementedException(); } }

Un intento / captura / finalmente confiable tendrá que usar Regiones de Ejecución Restringida (CER) . Un example es proporcionado por MSDN:

[StructLayout(LayoutKind.Sequential)] struct MyStruct { public IntPtr m_outputHandle; } sealed class MySafeHandle : SafeHandle { // Called by P/Invoke when returning SafeHandles public MySafeHandle() : base(IntPtr.Zero, true) { } public MySafeHandle AllocateHandle() { // Allocate SafeHandle first to avoid failure later. MySafeHandle sh = new MySafeHandle(); RuntimeHelpers.PrepareConstrainedRegions(); try { } finally { MyStruct myStruct = new MyStruct(); NativeAllocateHandle(ref myStruct); sh.SetHandle(myStruct.m_outputHandle); } return sh; } }

Una excelente fuente de información es el siguiente artículo:

Mejores prácticas de confiabilidad


No, no lo hace. Siempre se ejecutará siempre que la aplicación aún se esté ejecutando (excepto durante una excepción de FastFail , enlace de MSDN , como se indicó en otros). Se ejecutará cuando salga de la porción try / catch del bloque.

NO se ejecutará si la aplicación falla: se mata mediante un comando de proceso de eliminación, etc. Esto es muy importante, porque si escribe código que espera que se ejecute, como hacerlo manualmente, y si no lo hace, automáticamente confirmar, puede ejecutar en un escenario la aplicación aborta antes de que eso suceda. Honestamente, este es un escenario externo, pero es importante tomar nota en esas situaciones.


No, no.

Sin embargo, solo hay una forma de evitarlo y eso es Environment.FailFast() . Vea http://msdn.microsoft.com/de-de/library/ms131100.aspx . En cualquier otro caso, se garantiza que los finalizadores se ejecuten ;-)

El método FailFast escribe la cadena del mensaje en el registro de eventos de la aplicación Windows, crea un volcado de su aplicación y luego finaliza el proceso actual. La cadena del mensaje también se incluye en el informe de errores a Microsoft.

Utilice el método FailFast en lugar del método Exit para finalizar su aplicación si el estado de su aplicación está dañado sin posibilidad de reparación, y la ejecución de los bloques y finalizadores try / finally de su aplicación corromperá los recursos del programa.


Respuesta simple Sí. Pero hay algunas "excepciones" a la regla.


Sí, finally siempre se ejecuta, ahora si el código en el bloque finally causará una excepción es una historia diferente.


Sí, bajo circunstancias normales (como muchos otros han señalado).

El bloque finally es útil para limpiar cualquier recurso asignado en el bloque try así como para ejecutar cualquier código que deba ejecutarse incluso si hay una excepción. El control siempre pasa al bloque finally independientemente de cómo salga el bloque try.

Mientras que catch se utiliza para manejar excepciones que se producen en un bloque de instrucciones, finalmente se utiliza para garantizar que un bloque de instrucciones se ejecute independientemente de cómo se salga del bloque try anterior.

http://msdn.microsoft.com/en-us/library/zwc8s4fz.aspx