Есть ли способ определить действие для необработанных исключений в приложении WinForms .NET 3.5? - PullRequest
2 голосов
/ 30 сентября 2008

Обратите внимание, я понимаю, что это было адресовано здесь . В этом посте обсуждается обработка исключений в .NET 1.1, при этом подразумевается, что существует более подходящее решение для> .NET 2.0, поэтому этот вопрос конкретно относится к более новым версиям .NET.

У меня есть приложение для форм Windows, которое, как ожидается, часто и неожиданно теряет связь с базой данных, и в этом случае оно сбрасывает себя в исходное состояние.

Я уже веду журнал ошибок, повторное подключение и т. Д. Через набор декораторов в моем пользовательском объекте DBWrapper. Однако после того, как об этом позаботятся, я бы хотел, чтобы ошибка провалилась в стеке. Как только он достигнет вершины и станет необработанным, я бы хотел, чтобы он был проглочен и мой метод ApplicationResetter.Reset () был выполнен.

Может кто-нибудь сказать мне, как это сделать?

Если это невозможно, то существует ли хотя бы способ справиться с этим, не вводя зависимость от ApplicationResetter для каждого класса, который может получить такую ​​ошибку, и фактически не закрывая и не перезапуская мое приложение (что будет выглядеть уродливо)?

Ответы [ 5 ]

2 голосов
/ 30 сентября 2008

предостережение: еще не знаком с 3.5, возможно, будет лучший ответ ...

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

если вы уже обрабатываете случай db-not-there и пропускаете другие исключения, приложение должно умереть, поскольку оно может быть нестабильным

1 голос
/ 30 сентября 2008

Есть событие System.Windows.Forms.Application.ThreadException и System.AppDomain.CurrentDomain.UnhandledException.

Как упомянул Стивен, они оставят вашу заявку в неизвестном состоянии. В действительности нет другого способа сделать это, кроме как поместить вызов, который может вызвать исключение, в блок try / catch.

1 голос
/ 30 сентября 2008

Возможно, событие Application.ThreadException подойдет вашим потребностям:

static void Main()
{
    Application.ThreadException += Application_ThreadException;
    //...
 }

 static void Application_ThreadException(object sender, System.Threading.ThreadExceptionEventArgs e)
 {
     // call ApplicationResetter.Reset() here
 }
0 голосов
/ 01 октября 2008

Для потоков Windows Forms (которые вызывают Application.Run ()), назначьте обработчик ThreadException в начале Main (). Кроме того, я обнаружил, что необходимо вызвать SetUnhandledExceptionMode:

Application.SetUnhandledExceptionMode(UnhandledExceptionMode.Automatic);
Application.ThreadException += ShowUnhandledException;
Application.Run(...);

Вот пример обработчика. Я знаю, что это не то, что вы ищете, но он показывает формат обработчика. Обратите внимание, что если вы хотите, чтобы исключение было фатальным, вы должны явно вызвать Application.Exit ().

static void ShowUnhandledException(object sender, ThreadExceptionEventArgs t)
{
    Exception ex = t.Exception;
    try {
        // Build a message to show to the user
        bool first = true;
        string msg = string.Empty;
        for (int i = 0; i < 3 && ex != null; i++) {
            msg += string.Format("{0} {1}:\n\n{2}\n\n{3}", 
                first ? "Unhandled " : "Inner exception ",
                ex.GetType().Name,
                ex.Message, 
                i < 2 ? ex.StackTrace : "");
            ex = ex.InnerException;
            first = false;
        }
        msg += "\n\nAttempt to continue? (click No to exit now)";

        // Show the message
        if (MessageBox.Show(msg, "Unhandled exception", MessageBoxButtons.YesNo, MessageBoxIcon.Error) == DialogResult.No)
            Application.Exit();
    } catch (Exception e2) {
        try {
            MessageBox.Show(e2.Message, "Fatal error", MessageBoxButtons.OK, MessageBoxIcon.Stop);
        } finally {
            Application.Exit();
        }
    }
}
0 голосов
/ 30 сентября 2008

Довольно подробное объяснение необработанных исключений в последнем выпуске MSDN: сентябрь 2008

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...