C # необработанный обработчик исключений, пытающийся записать в файл журнала - PullRequest
3 голосов
/ 19 апреля 2011

Мое приложение - сервер Windows Forms .NET 4 C # TCP / IP. Это происходит сбой примерно один раз в день с общим сообщением о сбое Windows Server (нажмите закрыть, чтобы закрыть это приложение). Я вставил следующий код, чтобы перехватить любое исключение, которое может быть причиной этого, и вставил простой нулевой объект в процедуру, которая регулярно вызывается для генерации тестового исключения.

Две вещи:

  1. Когда возникает тестовое исключение, код отладки попадает в отладчик, файл создается и записывается, и все в порядке.
  2. Без отладчика я получаю сообщение «продолжить или выйти» .NET stacktrace и, независимо от того, что я выбираю, файл никогда не создается и не записывается.

. NET сообщение для меня бесполезно. Мне нужна трассировка стека лог-файла аварии. Кто-нибудь знает, как я могу это сделать? Спасибо.

static class Program
{
    [STAThread]
    static void Main(string[] rgszArgs)
    {
        //My exception handler
        AppDomain.CurrentDomain.UnhandledException +=
            new UnhandledExceptionEventHandler(CatchUnhandledException);

        Application.EnableVisualStyles();
        Application.SetCompatibleTextRenderingDefault(false);
        Application.Run(new FormMain(rgszArgs));
    }

    static void CatchUnhandledException
        (object sender, UnhandledExceptionEventArgs e)
    {
        StreamWriter sw;
        DateTime dtLogFileCreated = DateTime.Now;
        Exception ex;

        try
        {
            sw = new StreamWriter("crash-" + dtLogFileCreated.Day + dtLogFileCreated.Month
                        + dtLogFileCreated.Year + "-" + dtLogFileCreated.Second
                        + dtLogFileCreated.Minute + dtLogFileCreated.Hour + ".txt");

            ex = (Exception)e.ExceptionObject;

            sw.WriteLine("### Server Crash ###");
            sw.WriteLine(ex.Message + ex.StackTrace);
            sw.Close();
        }
        finally
        {
            Application.Exit();
        }
    }
}

Ответы [ 4 ]

5 голосов
/ 19 апреля 2011

Требуется событие Application.ThreadException .

Событие необработанных исключений AppDomain захватывает необработанные исключения, например, любые исключения, созданные методом Main, однако Application.Run обрабатывает исключения внутренне - это означает, что Application.Run не вызовет исключение в результате исключение в обработчике событий, поэтому CatchUnhandledException никогда не запускается.

Это означает, что если обработчик ThreadException смог восстановиться после исключения, приложение продолжит нормальную работу (если исключение было выдано Application.Run, восстановления не будет). По причинам, которые я не понимаю, это поведение отличается при отладке. . При отладке это поведение изменяется так, что создается исключение, позволяющее немедленно отлаживать исключения в Visual Studio - вот почему ваш обработчик необработанных исключений работает во время отладки.

Обратите внимание, что вышеуказанный обработчик CatchUnhandledException будет перехватывать исключения, создаваемые фоновыми потоками в домене вашего приложения.

См. Также Application.SetUnhandledExceptionMode .

1 голос
/ 19 апреля 2011

Я должен догадаться, что это обработчик события AppDomain.UnhandledException.Одна вещь, которую вы определенно не можете сделать, это вызвать Application.Exit (), программа больше не находится в правильном состоянии, чтобы закрываться, вы должны вызвать Environment.Exit ().Вызов Application.Exit () является вероятным источником сообщения «продолжить или выйти», которое звучит как ThreadExceptionDialog, который отображается приложением Winforms, и подвергается сердечной атаке в потоке пользовательского интерфейса.это аргумент, который вы передаете конструктору StreamWriter.Вы не указываете полный путь к файлу (например, c: \ mumble \ foo.txt), он может попытаться записать файл в каталог, к которому у вас нет прав записи.Очень вероятно, на Vista или Win7.Или файл действительно записан, но вы просто не можете найти его обратно, потому что не знаете, где искать.

Используйте Environment.GetFolderPath (), чтобы выбрать каталог, в который вы знаете, что можете писать.1005 *

0 голосов
/ 19 апреля 2011

Вы также можете попробовать позвонить Environment.FailFast("reason for failure here"), если состояние вашей программы находится в таком беспорядке, что любой код в блоке try / finally повредит вашу программу. Это автоматически запишет в журнал событий.

0 голосов
/ 19 апреля 2011

Это из MSDN для Событие AppDomain.UnhandledException :

Начиная с версии .NET Framework 4, это событие не вызывается для исключений, которые портят состояниепроцесс, такой как переполнение стека или нарушения доступа, если обработчик события не критичен к безопасности и не имеет атрибут HandleProcessCorruptedStateExceptionsAttribute.

Может ли это быть?

...