none
Как глобально обрабатывать все определенные исключения? RRS feed

  • Вопрос

  • Есть крупное приложение (оболочка базы данных).

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

    Можно ли как то обработать эту ошибку не вставляя везде в программе тысячи try...catch, причем сообщая пользователю в этом случае конкретику ошибки (отсутствие связи с сервером) и выдавая другой ответ если ошибка другого плана (баг, переполнение и т.п.)?

    Например (условно) при обрыве связи: "Нет доступа к серверу БД", а при попытке деления на 0: "Глобальная ошибка приложения"

    30 сентября 2011 г. 14:48

Ответы

  • Спасибо всем!

    Много раз посматривал в сторону АОП, но все оказалось намного проще:

    В Program.cs перед Application.Run(new Form_Вход());

     

                Application.SetUnhandledExceptionMode(UnhandledExceptionMode.CatchException);
                Application.ThreadException += All.Except;

    (где All - статический класс)

         public static void Except(object sender, System.Threading.ThreadExceptionEventArgs e)
            {
                if (e.Exception is SqlException)
                {
                    System.Windows.Forms.MessageBox.Show("Нет ответа от сервера.\nВозможные причины:"
                    + "\n- Неустойчивая связь по локальной сети или Интернету"
                    + "\n- Компьютер загружен другими приложениями и не успевает обработать ответ сервера"
                    + "\n- Сервер перегружен и не успевает обработать все запросы" + "\n"
                    + "\n- Рекомендации:"
                    + "\n- Проверить соединение с Интернетом"
                    + "\n- Перезагрузить компьютер",
                    "Ошибка соединения с сервером"MessageBoxButtons.OK, MessageBoxIcon.Error);
                    return;
                }
                if (e.Exception is OutOfMemoryException)
                {
                    System.Windows.Forms.MessageBox.Show("Не хватает оперативной памяти.\nВозможные причины:"
                    + "\n- На компьютере недостаточно оперативной памяти"
                    + "\n- Неисправные платы оперативной памяти в компьютере"
                    + "\n- Другое приложение использует всю доступную оперативную память"
                    + "\n- Компьютерный вирус в системе" + "\n"
                    + "\n- Рекомендации:"
                    + "\n- Проверить досаточно ли оперативной памяти у компьютера (рекомендуется минимум 512 Мб)"
                    + "\n- Проверить компьютер антивирусом"
                    + "\n- Перезагрузить компьютер",
                    "Ошибка памяти"MessageBoxButtons.OK, MessageBoxIcon.Error);
                    return;
                }
                //... дальнейшая обработка других ошибок
            }
    В общем приблизительно так :)

     


    • Изменено small_dragon 3 октября 2011 г. 14:33
    • Помечено в качестве ответа small_dragon 3 октября 2011 г. 14:34
    3 октября 2011 г. 14:33

Все ответы

    • Предложено в качестве ответа Abolmasov Dmitry 2 октября 2011 г. 22:32
    1 октября 2011 г. 9:44
    Модератор
  • Уважаемый пользователь, пожалуйста, не забудьте отметить сообщение или сообщения, которые являются решением вашей проблемы, даже если это ваше собстевенное сообщение. Это можно сделать с помощью кнопки 'Пометить как ответ', которая есть под каждым сообщением.

    Спасибо.


    Для связи [mail]
    2 октября 2011 г. 22:32
  • > Можно ли как то обработать эту ошибку не вставляя везде в программе тысячи try...catch

    если код методов менять не планируете, то:
    - инъекции с помощью Mono.Cecil; пример: http://stackoverflow.com/questions/4372205/how-to-inject-call-to-system-object-equals-with-mono-cecil
    - добавить AOP-атрибуты; http://stackoverflow.com/questions/1382922/mono-cecil-vs-postsharp-core-vs-microsoft-cci-for-implementing-aop-framework
    - изменить код во время компиляции (возможность появится с выходом Roslyn) http://social.msdn.microsoft.com/Forums/da-DK/async/thread/03a51936-b4fd-4814-9161-46544eda63cf

     

    3 октября 2011 г. 14:26
  • Спасибо всем!

    Много раз посматривал в сторону АОП, но все оказалось намного проще:

    В Program.cs перед Application.Run(new Form_Вход());

     

                Application.SetUnhandledExceptionMode(UnhandledExceptionMode.CatchException);
                Application.ThreadException += All.Except;

    (где All - статический класс)

         public static void Except(object sender, System.Threading.ThreadExceptionEventArgs e)
            {
                if (e.Exception is SqlException)
                {
                    System.Windows.Forms.MessageBox.Show("Нет ответа от сервера.\nВозможные причины:"
                    + "\n- Неустойчивая связь по локальной сети или Интернету"
                    + "\n- Компьютер загружен другими приложениями и не успевает обработать ответ сервера"
                    + "\n- Сервер перегружен и не успевает обработать все запросы" + "\n"
                    + "\n- Рекомендации:"
                    + "\n- Проверить соединение с Интернетом"
                    + "\n- Перезагрузить компьютер",
                    "Ошибка соединения с сервером"MessageBoxButtons.OK, MessageBoxIcon.Error);
                    return;
                }
                if (e.Exception is OutOfMemoryException)
                {
                    System.Windows.Forms.MessageBox.Show("Не хватает оперативной памяти.\nВозможные причины:"
                    + "\n- На компьютере недостаточно оперативной памяти"
                    + "\n- Неисправные платы оперативной памяти в компьютере"
                    + "\n- Другое приложение использует всю доступную оперативную память"
                    + "\n- Компьютерный вирус в системе" + "\n"
                    + "\n- Рекомендации:"
                    + "\n- Проверить досаточно ли оперативной памяти у компьютера (рекомендуется минимум 512 Мб)"
                    + "\n- Проверить компьютер антивирусом"
                    + "\n- Перезагрузить компьютер",
                    "Ошибка памяти"MessageBoxButtons.OK, MessageBoxIcon.Error);
                    return;
                }
                //... дальнейшая обработка других ошибок
            }
    В общем приблизительно так :)

     


    • Изменено small_dragon 3 октября 2011 г. 14:33
    • Помечено в качестве ответа small_dragon 3 октября 2011 г. 14:34
    3 октября 2011 г. 14:33
  • также см. AppDomain.CurrentDomain.UnhandledException += ...

    3 октября 2011 г. 14:58