Как реализовать один “catch'em весь” обработчик исключений с резюме?

30
задан Andrii Kalytiiuk 20 January 2014 в 12:19
поделиться

8 ответов

Если Вы запускаете приложение Windows Forms: добавьте обработчик к Application.ThreadException событие.

33
ответ дан Vincent Van Den Berghe 27 November 2019 в 23:13
поделиться

Я предполагаю, что Вы пишете Приложение Windows, в этом случае, да , можно сделать это. Я оставлю плюсы и минусы того, должны ли Вы другим. Уже существует достаточно ответов, которые смотрят на это, и я предлагаю, чтобы Вы рассмотрели их тщательно, прежде чем Вы на самом деле сделаете это .

Примечание, что этот код будет вести себя по-другому в отладчике, чем он, делает при запуске приложения непосредственно (другая причина не сделать это, возможно). Заставить приложение показывать messagebox и продолжать после этого Вас должно будет запустить приложение из проводника, не из Visual Studio.

Создают новое приложение форм Windows. Код в Program.cs выглядит примерно так:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading;
using System.Windows.Forms;

namespace WindowsFormsApplication2 {
    static class Program {
        /// <summary>
        /// The main entry point for the application.
        /// </summary>
        [STAThread]
        static void Main() {
            Application.EnableVisualStyles();
            Application.SetCompatibleTextRenderingDefault(false);
            Form1 form1 = new Form1();
            Application.ThreadException += new ThreadExceptionEventHandler(form1.UnhandledThreadExceptionHandler);
            Application.Run(form1);
        }
    }
}

Тогда заставляют код в Form1 выглядеть примерно так:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading;
using System.Windows.Forms;

namespace WindowsFormsApplication2 {
    public partial class Form1 : Form {
        public Form1() {
            InitializeComponent();
        }

        public void UnhandledThreadExceptionHandler(object sender, ThreadExceptionEventArgs e) {
            this.HandleUnhandledException(e.Exception);
        }

        public void HandleUnhandledException(Exception e) {
            // do what you want here.
            if (MessageBox.Show("An unexpected error has occurred. Continue?",
                "My application", MessageBoxButtons.YesNo, MessageBoxIcon.Stop,
                MessageBoxDefaultButton.Button2) == DialogResult.No) {
                Application.Exit();
            }
        }

        private void button1_Click(object sender, EventArgs e) {
            throw new ApplicationException("Exception");
        }

    }
}

(Добавляют button1 к форме и присоединяют его button1_Click.)

32
ответ дан Sam Meldrum 27 November 2019 в 23:13
поделиться

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

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

19
ответ дан Jon Skeet 27 November 2019 в 23:13
поделиться

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

4
ответ дан tvanfosson 27 November 2019 в 23:13
поделиться

Необходимо читать на всех проблемах, связанных с VB's" On Error Resume Next" стиль обработки ошибок. Это кажется, что Вы пытаетесь реализовать это для C#.

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

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

я думаю лучшее, которое можно сделать для восстановления с ошибки как, Вы описываете, должен поймать исключение на прикладном уровне, зарегистрировать проблему, сообщить пользователю (и потенциально генерируйте/отправьте своего рода проблемный отчет для Вас), и перезапустите приложение. Конечно, при ловле исключения ближе в проблемную область тот обработчик имеет шанс сделать что-то немного более интеллектуальное, таким образом, Вы не должны полагаться на обработчик уровней приложения как на опору - так же, как отказоустойчивое.

-1
ответ дан Michael Burr 27 November 2019 в 23:13
поделиться

В некоторых версиях.NET можно на самом деле поместить ловца вокруг Приложения. Выполненный () (Вы найдете это в program.cs) и это должно поймать исключения всего Основного Потока однако в большинстве случаев это, возможно, плохой дизайн и привычка дают Вам большую часть возможности "возобновиться". Дополнительно Вы будете всегда , должны вручную обработать любые исключения на фоновых потоках.

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

-1
ответ дан Quibblesome 27 November 2019 в 23:13
поделиться

Это просто кричит плохой дизайн на всем протяжении. Никогда не используйте исключения для вещей как это. Исключения ТОЛЬКО, чтобы использоваться, когда что-то, программист не намеревался, происходит.

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

-2
ответ дан Filip Ekberg 27 November 2019 в 23:13
поделиться

Блок приложений Обработки исключений Библиотеки Microsoft Enterprise имеет примеры того, как можно сделать это.

В основном Вы окружаете код, который может выдать исключения с этим:

try
{
  MyMethodThatMightThrow();
}
catch(Exception ex)
{
   bool rethrow = ExceptionPolicy.HandleException(ex, "SomePolicy");
   if (rethrow) throw;
}

Тогда можно настроить политику показать диалоговое окно пользователю и спросить, хочет ли она продолжить.

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

-3
ответ дан Doug L. 27 November 2019 в 23:13
поделиться
Другие вопросы по тегам:

Похожие вопросы: