2011-02-01 22 views
5

Duplicar posible:
Finally Block Not Running??finalmente bloquear en C#

Tengo una pregunta con respecto bloque finally en C#. escribí un pequeño código de ejemplo:

public class MyType 
{ 
    public void foo() 
    { 
     try 
     { 
      Console.WriteLine("Throw NullReferenceException?"); 
      string s = Console.ReadLine(); 
      if (s == "Y") 
       throw new NullReferenceException(); 
      else 
       throw new ArgumentException();   
     } 
     catch (NullReferenceException) 
     { 
      Console.WriteLine("NullReferenceException was caught!"); 
     } 
     finally 
     { 
      Console.WriteLine("finally block"); 
     } 
    } 
} 

class Program 
{ 
    static void Main(string[] args) 
    { 
     MyType t = new MyType(); 
     t.foo(); 
    } 
} 

Mientras que yo sepa, finally supone que debe funcionar deterministicly, sea o no una excepción fue arrojado. Ahora, si el usuario ingresa "Y" - se lanza NullReferenceException, la ejecución se mueve al reloj catch y luego al bloque finally como esperaba. Pero si la entrada es otra cosa, se lanza ArgumentException. No existe un bloque catch adecuado para detectar esta excepción, así que pensé que la ejecución debería mover el bloque finally, pero no es así. ¿Podría alguien por favor explicarme por qué?

gracias a todos :)

+2

posible duplicar: http://stackoverflow.com/questions/4193493/finally-block-not-running –

+2

He intentado con el código, y entra en el bloque finally como se esperaba – SWeko

+0

¿Puedes aclarar a qué te refieres con ' Pensé que la ejecución debería mover el bloque final. Supongo que el control irá al final en ambos casos, ¿no? – InSane

Respuesta

6

Su depurador es, probablemente, la captura de la ArgumentException por lo que está esperando a "manejar" que hay antes de entrar en el bloque final. Ejecute su código sin un depurador adjunto (incluido sin su depurador JIT) y debería golpear su bloque finally.

Para deshabilitar JIT, ir a Opciones> Herramientas> Depuración> Just-In-Time y desactive Managed

Para depurar w/o un depurador asociado, en Visual Studio van a Test> Inicio sin depurar (o CTRL + F5)

también sería útil poner un Console.ReadLine() al final de su programa de prevención de la consola se cierre después de entrar en el bloque finally.

class Program { 
    static void Main(string[] args) { 
     MyType t = new MyType(); 
     t.foo(); 
     Console.ReadLine(); 
    } 
} 

Aquí está la salida que debe obtener:


Throw NullReferenceException? N

Excepción no controlada: System.ArgumentException: el valor no está dentro del rango especificado.

en ConsoleSandbox.MyType.foo() en P: \ documentos \ Sandbox \ Console \ Console \ Consol e \ Program.cs: Línea 17

en ConsoleSandbox.Program.Main (String [] args) en P: \ Documents \ Sandbox \ Console \ Console \ Console \ Program.cs: línea 31

finalmente se bloquean

Pulse cualquier tecla para continuar. . .

+0

Bueno, tienes razón. No creo que esté relacionado con el depurador porque probé las 4 combinaciones de 'Lanzado' y 'Usuario-No controlado' de las Excepciones de tiempo de ejecución de CLR en la ventana de Excepción. ¿No es eso relacionado? Quiero decir, si desactivé esas casillas, ¿no debería funcionar el código sin interferencia? Gracias de nuevo, por tu tiempo. – meem

+0

Te refieres a las opciones [Depurar> Excepciones]; eso es diferente de las opciones de depurador Just-In-Time que mencioné anteriormente. El depurador JIT detectará las excepciones NO HABILADAS, mientras que las opciones de excepciones a las que se refiere es el depurador adjunto de Visual Studio. – bitxwise

+0

Entendido. ¡Gracias! – meem

1

Lo que ve es un artefacto de su programa de prueba.

Si cambia su método principal:

static void Main(string[] args) 
{ 
    try 
    { 
     MyType t = new MyType(); 
     t.foo(); 
    } 
    catch 
    { 
     // write something 
    } 
} 

Luego, su foo() se comportará como se espera.

Sin ese toplevel try/catch, se ha cancelado todo su programa.