Как я могу сделать что-то, что перехватывает все «необработанные» исключения в приложении WinForms? - PullRequest
77 голосов
/ 23 апреля 2011

До сих пор я просто помещал блок try / catch вокруг Application.Run в точке входа Program.cs в программу. Это ловит все исключения достаточно хорошо в режиме отладки, но когда я запускаю программу без режима отладки, исключения больше не обрабатываются. Я получаю необработанное окно исключения.

Я не хочу, чтобы это случилось. Я хочу, чтобы все исключения были перехвачены при работе в режиме без отладки. Программа имеет несколько потоков, и желательно, чтобы все исключения из них перехватывались одним и тем же обработчиком; Я хочу регистрировать исключения в БД. У кого-нибудь есть советы, как это сделать?

Ответы [ 4 ]

100 голосов
/ 23 апреля 2011

Взгляните на пример из ThreadException документации :

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);
}

Возможно, вы также захотите не перехватывать исключения при отладке, поскольку это облегчает отладку. Это что-то вроде хака, но для этого вы можете обернуть вышеупомянутый код с помощью

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

Для предотвращения перехвата исключений при отладке.

26 голосов
/ 23 апреля 2011

В NET 4 некоторые исключения больше не перехватываются по умолчанию; это, как правило, исключения, которые указывают на (возможно фатальное) поврежденное состояние исполняемого файла, например AccessViolationException.

Попробуйте использовать тег [HandleProcessCorruptedStateExceptions] перед вашим основным методом, например

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;
  } 
17 голосов
/ 12 ноября 2015

Хороший пример можно найти по адресу http://www.csharp -examples.net / catching-unhandled-exceptions / В основном, измените ваш основной на:

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");
    }
8 голосов
/ 23 апреля 2011

Для этого вы можете использовать библиотеку NBug .С минимальной настройкой, подобной этой:

NBug.Settings.Destination1 = "Type=Mail;From=me@mycompany.com;To=bugtracker@mycompany.com;SmtpServer=smtp.mycompany.com;";
AppDomain.CurrentDomain.UnhandledException += NBug.Handler.UnhandledException;
Application.ThreadException += NBug.Handler.ThreadException;

Вы можете начать собирать информацию обо всех необработанных ошибках в вашем приложении, даже когда оно развернуто на клиентах.Если вы не хотите использовать стороннюю библиотеку, вам следует присоединиться к следующим событиям:

// These two should come before enabling visual styles or running the application
AppDomain.CurrentDomain.UnhandledException += ...
Application.ThreadException += ...
...
Application.Run(new Form1());
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...