2009-07-30 12 views
13

Tengo una aplicación de winforms. Las mejoras comienzan con Program.cs donde tenemos definido main(). He puesto este código en el bloque try-catch.Por qué la excepción win32 no se detecta mediante el mecanismo de manejo de excepciones C#

[STAThread] 
    static void Main() 
    { 
     try 
     { 
      Application.EnableVisualStyles(); 
      Application.SetCompatibleTextRenderingDefault(false); 
      Application.Run(new frmSplash()); 
     } 
     catch (Exception ex) 
     { 
      MessageBox.Show(ex.Message); 
      if (ex.InnerException != null) 
      { 
       MessageBox.Show(ex.InnerException.ToString()); 
      } 
     } 
    } 

Siempre que hay una excepción Win32, este mecanismo falla y el mensaje de excepción no controlada se lanza y se bloquea la aplicación.
Tengo 2 preguntas con respecto a este código:

1) Por qué las excepciones de win32 no se detectan.

2) ¿Es una buena práctica detectar excepciones al más alto nivel.

+0

Guau, nunca pensé en esto, buena pregunta y buenas respuestas :) – leppie

+0

Comente también la segunda pregunta. – Rohit

+0

Tal vez podría hacer una segunda pregunta ASÍ ;-) – Mac

Respuesta

12

EDIT: como Pratik señaló, la siguiente respuesta se aplica a .NET 1.0 y .NET 1.1 solamente. Comenzando con .NET 2.0, la excepción que no es CLS debe tomarse como RuntimeWrappedException.


Porque las excepciones de Win32 no se derivan de la clase .NET Exception. Proveedores:

try { 
} catch (Exception ex) { 
    // .NET exception 
} catch { 
    // native exception 
} 

Ver Catch non-CLSCompliant exceptions in general handlers para más información.

+4

Esto no es obligatorio en .Net 2.0 por defecto. Todas las excepciones que no son CLS son rapeadas como RuntimeWrappedException. Consulte http://msdn.microsoft.com/en-us/library/ms404228.aspx – softveda

+0

Win32Exception

+0

@Pratik: gracias por el enlace. @Tommy Carlier: cf. El enlace de Pratik ... – Mac

0

Es posible que tenga que coger Win32Exception (o ExternalException) en lugar

http://msdn.microsoft.com/en-us/library/system.componentmodel.win32exception.aspx

Me parece recordar que Win32Exception hereda de ExternalException pero ExternalException no hereda de Excepción por lo que no será atrapado por su código .

Editar: ¡Vea otras respuestas para saber por qué esto está mal!

Edición 2: En cuanto a la segunda parte, según lo declarado por AnthonyWJones Es de buena educación que el usuario sepa que un problema ha causado la aplicación para cerrar, sin embargo, recomendaría el uso de una declaración Inglés claro para el usuario y registrar la pila de excepciones en un archivo de registro para su propio uso.

+1

Ambos son derivados de la excepción, por lo tanto, en la superficie de la misma debería funcionar la captura en la pregunta. Por qué no es ver mi respuesta. – AnthonyWJones

3

La ejecución de Application.Run no arroja un error. Eso está sucediendo en otro hilo (o al menos de forma asíncrona).

Es una buena idea informar al usuario de manera amigable que la aplicación ha fallado antes de desaparecer por completo, sin embargo, no es una buena idea capturar y continuar.

3

Si bien no sé por qué su bloque catch no funciona, intente utilizar el Application ThreadException Event. Esto debería detectar cualquier error en los hilos de la aplicación. Agregue un controlador de eventos antes de llamar a Application.Run.

Para su segunda respuesta definitivamente sí. Desarrollo y mantengo una aplicación de winforms empresarial que habla con un backend de servicio web en hilos de fondo. Si los bloqueos de llamada de un servicio web manejan el evento threadexception de la aplicación (y también appdomain unhandledexception), inicie sesión y aparezca un error que los usuarios comerciales pueden informar y les permite continuar sin bloquear la aplicación.

0

1) Las excepciones de Win32 deben capturarse. ¿Tal vez la excepción se lanza desde un hilo de fondo o el hilo de GC?

2) Depende de la estructura de su aplicación. Por ejemplo, si tu IU de notificación de error estaba vinculada a la forma principal de alguna manera (por ejemplo, necesitas invocar el hilo UI desde un hilo de trabajo), sería una tontería mostrar una UI en un bloque de código fuera del código que ejecuta el mensaje lazo. Sin embargo, si su ejemplo de código es de subproceso único, estaría bien.

1

Probar la suscripción de estos eventos antes de que comience la aplicación (Application.Run):

A continuación, puede deshacerse de su try catch bloque.


Creo que es una mala práctica detectar excepciones al más alto nivel, ¡pero no se puede evitar! Durante el desarrollo (depuración), esas excepciones no deberían ser detectadas y la aplicación debería hacer lo más desagradable posible (¿falla?). En producción (versión), querrá que su aplicación se degrade lo mejor posible incluso cuando ocurran excepciones no controladas. Este es uno de los pocos usos que encontré para el DEBUG preprocessor variable.

+0

Aquí tienes: 2 respuestas en una. ¿A cuál vas a ir (o en contra)? – Mac

Cuestiones relacionadas