2011-11-16 12 views
17

He implementado un software que tiene una biblioteca DLL que contiene un gran conjunto de clases que incluye todos los métodos para mi software.WinForms Global Exception Handling?

Ahora quiero ser capaz de manejar algunos errores globales como el error # 26 que no es un Error relacionado con la red en todas estas clases en lugar de ir a cada clase y agregarlo. Como hacer eso ?

Respuesta

12

Si #26 es una excepción, puede usar el evento AppDomain.CurrentDomain.UnhandledException. Si solo es un valor de retorno, entonces no veo ninguna posibilidad de manejarlo globalmente.

+1

dónde colocar esta pieza de código, si usted tiene cualquier referencia o puede publicar un ejemplo, estaré muy bien, lleno. – ykh

+0

Ver el enlace de MSDN en mi respuesta. Tiene un ejemplo: http://msdn.microsoft.com/en-us/library/system.appdomain.unhandledexception.aspx – gideon

23

Como es una aplicación de winforms, puede incluir Application.Run(new MainForm()); en un bloque try catch.

static void Main() 
{ 
try { 
Application.Run(new MainForm()); 
} catch(SystemException)//just as an example 
{ 
//log or handle the error here. 
} 
} 

No conozco ninguna implicación que podría causar este tipo de solución, pero acabo de decirle lo que necesitaba.

Otras opciones se suscriben al evento Application.ThreadException.

leer más aquí: unhandledexceptions

También hay AppDomain.UnhandledException y usted debe leer la diferencia entre ellos here on MSDN.

De MSDN:

Para ciertos modelos de aplicación, el evento UnhandledException pueda ser substituida por otros eventos si la excepción no controlada se produce en el hilo principal de la aplicación.

En las aplicaciones que usan Windows Forms, las excepciones no controladas en el subproceso principal de la aplicación provocan que se genere el evento Application.ThreadException. Si se maneja este evento, el comportamiento predeterminado es que la excepción no controlada no finaliza la aplicación, aunque la aplicación se deja en un estado desconocido. En ese caso, el evento UnhandledException no se genera. Este comportamiento se puede cambiar utilizando el archivo de configuración de la aplicación o utilizando el método Application.SetUnhandledExceptionMode para cambiar el modo a UnhandledExceptionMode.ThrowException antes de que el controlador de eventos ThreadException se conecte. Esto se aplica solo al hilo principal de la aplicación. El evento UnhandledException se genera para las excepciones no controladas lanzadas en otros hilos.

-1

Como una extensión de lo que se muestra arriba, utilizo el siguiente:

try 
{ 
    Application.Run(new FormMain()); 
} 
catch (Exception ex) 
{ 
    RoboReporterConstsAndUtils.HandleException(ex); 
} 

... donde el método HandleException() puede ser algo como:

internal static void HandleException(Exception ex) 
{ 
    var exDetail = String.Format(ExceptionFormatString, 
     ex.Message, 
     Environment.NewLine, 
     ex.Source, 
     ex.StackTrace, 
     ex.InnerException); 

    ExceptionLoggingService.Instance.LogAndEmailExceptionData(string.Format("{0}: {1}: {2}", 
     DateTime.Now.ToLongDateString(), GetVersionInfo(), exDetail)); 
} 

Otra forma de piel este gato es:

static void Main() 
{ 
    Application.EnableVisualStyles(); 
    Application.SetCompatibleTextRenderingDefault(false); 
    AppDomain.CurrentDomain.UnhandledException += Unhandled; 
    Application.Run(new FormMain()); 
} 

static void Unhandled(object sender, UnhandledExceptionEventArgs exArgs) 
{ 
    ExceptionLoggingService.Instance.LogAndEmailMessage(String.Format 
     ("From application-wide exception handler: {0}", exArgs.ExceptionObject)); 
} 

Por supuesto, se puede hacer lo que quiera dentro del método no controlada().

6

Con la referencia de Centralized Exception Handling en C# aplicación de Windows, me encontré con uno de buena solución:

static class Program 
{ 
    [STAThread] 
    static void Main() 
    { 
     // Add handler to handle the exception raised by main threads 
     Application.ThreadException += 
     new System.Threading.ThreadExceptionEventHandler(Application_ThreadException); 

     // Add handler to handle the exception raised by additional threads 
     AppDomain.CurrentDomain.UnhandledException += 
     new UnhandledExceptionEventHandler(CurrentDomain_UnhandledException); 

     Application.EnableVisualStyles(); 
     Application.SetCompatibleTextRenderingDefault(false); 
     Application.Run(new Form1()); 

     // Stop the application and all the threads in suspended state. 
     Environment.Exit(-1);    
    } 

    static void Application_ThreadException 
     (object sender, System.Threading.ThreadExceptionEventArgs e) 
    {// All exceptions thrown by the main thread are handled over this method 

     ShowExceptionDetails(e.Exception); 
    } 

    static void CurrentDomain_UnhandledException 
     (object sender, UnhandledExceptionEventArgs e) 
    {// All exceptions thrown by additional threads are handled in this method 

     ShowExceptionDetails(e.ExceptionObject as Exception); 

     // Suspend the current thread for now to stop the exception from throwing. 
     Thread.CurrentThread.Suspend(); 
    } 

    static void ShowExceptionDetails(Exception Ex) 
    { 
     // Do logging of exception details 
     MessageBox.Show(Ex.Message, Ex.TargetSite.ToString(), 
       MessageBoxButtons.OK, MessageBoxIcon.Error); 
    } 
} 

En la clase anterior, vamos a asociar un controlador de eventos para dos eventos. Es mejor adjuntar estos eventos tan pronto como comience el método principal.

Application.ThreadException - Este evento se generará cuando se genere una excepción en el hilo principal. Si agregamos un manejador de eventos, entonces la excepción se maneja sobre el método.

AppDomain.CurrentDomain.UnhandledException - Este evento se generará cuando se genere una excepción en los subprocesos adicionales utilizados en la aplicación. El peor escenario aquí es que, tan pronto como la ejecución de los controladores termina, la excepción se lanza de nuevo mientras la aplicación finaliza. Esto necesita ser manejado. Aquí he usado un poco de código para manejar esta situación y continuar la ejecución de la aplicación sin interrupción.

La lógica que he utilizado para superar esta situación es simplemente suspender el hilo en el controlador de eventos, para que la aplicación siga funcionando bien. Nuevamente surge un problema al suspender este hilo. Cuando se cierra el formulario principal, la aplicación normalmente necesita salir, pero como el hilo está en estado suspendido, la aplicación seguirá ejecutándose. Por lo tanto, para salir de la aplicación por completo y detener el proceso, se debe llamar a Environment.Exit (-1) antes de que finalice el método principal.

3

En primer lugar, se debe añadir:

Application.SetUnhandledExceptionMode(UnhandledExceptionMode.CatchException); 

Después que usted puede capturar las excepciones, por ejemplo:

[STAThread] 
    static void Main() 
    { 

     Application.EnableVisualStyles(); 
     Application.SetCompatibleTextRenderingDefault(false); 
     Application.SetUnhandledExceptionMode(UnhandledExceptionMode.CatchException); 
     Application.ThreadException += ApplicationThreadException; 
     AppDomain.CurrentDomain.UnhandledException += CurrentDomainOnUnhandledException; 

     if (DataBaseMNG.Init()) 
     { 
      Application.Run(new MainForm()); 
     } 
    } 

    /// <summary> 
    /// Global exceptions in Non User Interfarce(other thread) antipicated error 
    /// </summary> 
    /// <param name="sender"></param> 
    /// <param name="e"></param> 
    private static void CurrentDomainOnUnhandledException(object sender, UnhandledExceptionEventArgs e) 
    { 
     var message = 
      String.Format(
       "Sorry, something went wrong.\r\n" + "{0}\r\n" + "{1}\r\n" + "please contact support.", 
       ((Exception)e.ExceptionObject).Message, ((Exception)e.ExceptionObject).StackTrace); 
     MessageBox.Show(message, @"Unexpected error"); 
    } 

    /// <summary> 
    /// Global exceptions in User Interfarce antipicated error 
    /// </summary> 
    /// <param name="sender"></param> 
    /// <param name="e"></param> 
    private static void ApplicationThreadException(object sender, ThreadExceptionEventArgs e) 
    { 
     var message = 
      String.Format(
       "Sorry, something went wrong.\r\n" + "{0}\r\n" + "{1}\r\n" + "please contact support.", 
       e.Exception.Message, e.Exception.StackTrace); 
     MessageBox.Show(message, @"Unexpected error"); 
    }