2010-04-27 19 views
6

Considérese la siguiente aplicación sencilla: una forma de ventanas creado por una secuencia "nueva aplicación de Windows en C#" en VS que fue modificada en un siguiente manera:La captura de excepción en el principal método()

public static void Main() 
{ 
    Application.EnableVisualStyles(); 
    Application.SetCompatibleTextRenderingDefault(false); 

    try 
    { 
     Application.Run(new Form1()); 
    } 
    catch (Exception ex) 
    { 
     MessageBox.Show("An unexpected exception was caught."); 
    } 

} 

Form1.cs contiene las siguientes modificaciones:

private void Form1_Load(object sender, EventArgs e) 
{ 
    throw new Exception("Error"); 

} 

Si presiono F5 en el IDE, y luego, como espero, veo un cuadro de mensaje que indica que la excepción fue capturado y la aplicación se cierra.

Si voy a depurar (o liberar)/bin y ejecutar el ejecutable, veo la ventana estándar de "excepción no controlada", lo que significa que mi controlador de excepción no funciona.

Obviamente, eso tiene algo que ver con la excepción lanzada desde un hilo diferente desde el que se llama a Application.Run. Pero la pregunta sigue siendo: ¿por qué el comportamiento difiere dependiendo de si la aplicación se ha ejecutado desde IDE o desde la línea de comandos? ¿Cuál es la mejor práctica para asegurarse de que no quedan excepciones en la aplicación?

+0

@ Corvin: verifique una respuesta aceptada, si cree que ha encontrado una solución a su pregunta. –

Respuesta

10

Normalmente Application.ThreadException manejará la excepción en el evento Load. Obtendrá el ThreadExceptionDialog que ofrece las opciones Salir y Continuar.

Pero no cuando se instala un depurador. La cláusula de captura en el bucle de mensaje que muestra el cuadro de diálogo se desactiva de forma intencionada en ese caso. Eso es necesario porque sería muy difícil solucionar las excepciones si ese cuadro de diálogo aparece cuando depura un programa. Que este receptor ya no está activo, tu cláusula catch en el método Main() ahora tiene una oportunidad en la excepción.

Puede hacerlo coherente utilizando Application.SetUnhandledExceptionMode() en el método Main(). No deberías, las excepciones realmente son difíciles de depurar si haces esto. Si desea personalizar el manejo de excepciones para el hilo de interfaz de usuario a continuación, debe registrar su propio manejador Application.ThreadException:

if (!System.Diagnostics.Debugger.IsAttached) 
    Application.ThreadException += myThreadException; 

Atrapar excepciones no controladas en los subprocesos de trabajo requiere un controlador AppDomain.UnhandledException. No son recuperables.

También tenga cuidado con un error en Windows de 64 bits, las excepciones en el evento Load se tragan sin diagnóstico cuando se conecta un depurador. Fuerza el modo AnyCPU para evitar esa trampa.

+0

@Hans - ¿Te refieres al evento 'Form.Load'? Por cierto, buena escritura. –

+0

@Peter: sí. ¡Gracias! –

Cuestiones relacionadas