2011-04-23 29 views
65

Hasta ahora, sólo hay que poner un bloque try/catch alrededor del Application.Run en el punto de Program.cs entrada al programa. Esto captura todas las excepciones lo suficientemente bien en el modo de depuración, pero cuando ejecuto el programa sin el modo de depuración, las excepciones ya no se manejan. Obtengo el cuadro de excepción no controlada.¿Cómo puedo hacer algo que atrape todas las excepciones 'no controladas' en una aplicación WinForms?

no quiero que esto suceda. Quiero capturar todas las excepciones cuando se ejecuta en modo no depuración. El programa tiene múltiples hilos y, preferiblemente, todas las excepciones de ellos quedan atrapados por el mismo controlador; Quiero registrar excepciones en el DB. ¿Alguien tiene algún consejo sobre cómo hacer esto?

Respuesta

87

Tome un vistazo al ejemplo de la ThreadException documentation:

public static void Main(string[] args) 
{ 
    // Add the event handler for handling UI thread exceptions to the event. 
    Application.ThreadException += new  
    ThreadExceptionEventHandler(ErrorHandlerForm.Form1_UIThreadException); 

    // Set the unhandled exception mode to force all Windows Forms errors 
    // to go through our handler. 
    Application.SetUnhandledExceptionMode(UnhandledExceptionMode.CatchException); 

    // Add the event handler for handling non-UI thread exceptions to the event. 
    AppDomain.CurrentDomain.UnhandledException += new  
    UnhandledExceptionEventHandler(CurrentDomain_UnhandledException); 
} 

También puede ser que desee sin detectar excepciones cuando se depura, ya que esto facilita la depuración. Es algo así como un corte, pero para eso se puede envolver el código anterior por ahí con

if (!AppDomain.CurrentDomain.FriendlyName.EndsWith("vshost.exe")) { ... } 

Para evitar la captura de las excepciones al depurar.

+1

Hice un trabajador de segundo plano, y en el controlador de eventos dowork causé una excepción de referencia nula. Sin embargo, no fue atrapado por AppDomain.CurrentDomain.UnhandledException a pesar de establecer estos: Application.ThreadException + = new System.Threading.ThreadExceptionEventHandler (Application_ThreadException); Application.SetUnhandledExceptionMode (UnhandledExceptionMode.CatchException); AppDomain.CurrentDomain.UnhandledException + = new UnhandledExceptionEventHandler (CurrentDomain_UnhandledException); –

+3

@IsaacB, el trabajador de segundo plano capta excepciones en sí mismo. Puede verificar la excepción en RunWorkerCompleted incluso, mirando la propiedad RunCompletedEventArgs.Error. –

+1

Puede probar el manejo de excepciones para hilos adicionales al poner esto en OnLoad de su formulario principal. nuevo Thread (() => {throw new Exception();}). Start(); Desafortunadamente –

8

Puede utilizar NBug biblioteca para eso. Con una configuración mínima de esta manera:

NBug.Settings.Destination1 = "Type=Mail;[email protected];[email protected];SmtpServer=smtp.mycompany.com;"; 
AppDomain.CurrentDomain.UnhandledException += NBug.Handler.UnhandledException; 
Application.ThreadException += NBug.Handler.ThreadException; 

Usted puede comenzar a recoger información sobre todos los errores no controlada en su aplicación, incluso cuando está desplegado a los clientes. Si no desea utilizar una biblioteca tercera parte, se debe adjuntar a continuación eventos:

// These two should come before enabling visual styles or running the application 
AppDomain.CurrentDomain.UnhandledException += ... 
Application.ThreadException += ... 
... 
Application.Run(new Form1()); 
+1

de qué. Utilice el foro de discusión del proyecto NBug si tiene más preguntas (http://www.nbusy.com/forum/f11/) o use la etiqueta [nbug] aquí. –

+0

Por supuesto, también puede suscribirse un controlador de eventos "normal" para el evento UnhandledException. Ver http://msdn.microsoft.com/en-us/library/system.appdomain.unhandledexception.aspx – neo2862

+0

Chicos en Win7 + VS10, si me suscribo a estos eventos, la suscripción no se ejecuta, sino el Windows Vista/normal El cuadro de diálogo 7 muestra "Comprobar en línea para una solución" o "Cerrar el programa" ... etc. Pero si NO me suscribo, obtengo la ventana de excepción genérica .NET no controlada. Esto sucede tanto en las compilaciones Release como Debug, también intentó configurar 'Application.SetUnhandledExceptionMode (UnhandledExceptionMode.CatchException);' No cambia nada. – gideon

24

En NET 4, ciertas excepciones son no longer caught by default; estas tienden a ser excepciones que indican un estado (posiblemente fatal) corrupto del ejecutable, como AccessViolationException.

Pruebe usar la etiqueta [HandleProcessCorruptedStateExceptions] delante de su método principal, p.

using System.Runtime.ExceptionServices.HandleProcessCorruptedStateExceptions 

[HandleProcessCorruptedStateExceptions] 
public static int Main() 
{ 
    try 
    { 
     // Catch any exceptions leaking out of the program 
     CallMainProgramLoop(); 
    } 
    catch (Exception e) // We could be catching anything here 
    { 
     System.Console.WriteLine(e.Message); 
     return 1; 
    } 
    return 0; 
    } 
+0

¿Puedo usar 'AppDomain.CurrentDomain.UnhandledException' y' Application.ThreadException' también con la etiqueta '[HandleProcessCorruptedStateExceptions]'? – Kiquenet

6

Un buen ejemplo se puede encontrar en http://www.csharp-examples.net/catching-unhandled-exceptions/ Básicamente, cambie su principal a:

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

     Application.ThreadException += new ThreadExceptionEventHandler(Application_ThreadException); 
     Application.SetUnhandledExceptionMode(UnhandledExceptionMode.CatchException); 
     AppDomain.CurrentDomain.UnhandledException += new UnhandledExceptionEventHandler(CurrentDomain_UnhandledException); 

     Application.Run(new Form1()); 
    } 

    static void Application_ThreadException(object sender, ThreadExceptionEventArgs e) 
    { 
     MessageBox.Show(e.Exception.Message, "Unhandled Thread Exception"); 
    } 

    static void CurrentDomain_UnhandledException(object sender, UnhandledExceptionEventArgs e) 
    { 
     MessageBox.Show((e.ExceptionObject as Exception).Message, "Unhandled UI Exception"); 
    } 
Cuestiones relacionadas