Обработка исключений для событий

Я приношу извинения, если это - простой вопрос (мой Google-Fu может быть плохим сегодня).

Вообразите это приложение WinForms, которое имеет этот тип дизайна: Главное приложение-> показывает одно диалоговое окно->, что 1-е диалоговое окно может показать другое диалоговое окно. Оба из диалоговых окон имеют OK/кнопки отмены (ввод данных).

Я пытаюсь выяснить некоторый тип глобальной обработки исключений вроде Приложения. ThreadException. То, что я имею в виду:

Каждое из диалоговых окон будет иметь несколько обработчиков событий. 2-е диалоговое окно может иметь:

private void ComboBox_SelectedIndexChanged(object sender, EventArgs e)
{
    try
    {      
        AllSelectedIndexChangedCodeInThisFunction();
    }
    catch(Exception ex)
    {
        btnOK.enabled = false;  // Bad things, let's not let them save
        // log stuff, and other good things
    }
}

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

Но, я хочу избежать попытки/выгоды в каждом обработчике событий (если я мог). Недостаток всех они попытка/выгода является этим:

private void someFunction()
{
    // If an exception occurs in SelectedIndexChanged,
    // it doesn't propagate to this function
    combobox.selectedIndex = 3; 
}

Я не верю тому Приложению. ThreadException является решением, потому что я не хочу, чтобы исключение упало полностью-назад на 1-е диалоговое окно и затем главное приложение. Я не хочу закрывать приложение, я просто хочу зарегистрировать его, отобразить сообщение и позволить им отменить из диалогового окна. Они могут решить, что сделать оттуда (возможно, идут где-то в другом месте в приложении).

В основном, "глобальный обработчик", промежуточный 1-е диалоговое окно и 2-е (и затем, я предполагаю, другой "глобальный обработчик", промежуточный главное приложение и 1-е диалоговое окно).

7
задан Uwe Keim 10 May 2018 в 15:52
поделиться

5 ответов

Вы можете использовать обработчик AppDomain.CurrentDomain.UnhandledException , чтобы перехватывать ошибки в основном потоке пользовательского интерфейса и обрабатывать их для каждого диалога. Из MSDN:

В приложениях, использующих формы Windows , необработанные исключения в основном потоке приложения вызывают событие Application.ThreadException {{1 }} быть воспитанным. Если это событие обрабатывается , поведение по умолчанию таково, что необработанное исключение не завершает приложение, хотя приложение остается в неизвестном {{ 1}} состояние. В этом случае событие UnhandledException не возникает . Это поведение можно изменить с помощью файла конфигурации приложения или с помощью метода Application.SetUnhandledExceptionMode для изменения режима к UnhandledExceptionMode.ThrowException перед подключением обработчика события ThreadException . Это применимо только к основному потоку приложения. Событие UnhandledException вызывается для необработанных исключений, созданных в других потоках.

1
ответ дан 6 December 2019 в 21:11
поделиться

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

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

Обработка исключений может быть выполнена в родительском диалоговом окне.

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

например.

MyDialog myDialog = new MyDialog();
myDialog.Init(//data for the user to choose/manipulate);
if(myDialog.ShowDialog() == DialogResult.OK)
{
try{
ProcessDialogData(myDialog.SomeDataObject);
}
catch(/*...*/}
}

HTH

1
ответ дан 6 December 2019 в 21:11
поделиться

Да, обработка исключения Application.ThreadException по умолчанию была ошибкой . К сожалению, это была неизбежная ошибка, необходимая для того, чтобы сразу же не обескураживать и не разочаровывать сотни тысяч программистов, пишущих свое первое приложение Windows Forms.

Исправление, которое вы обдумываете, не является исправлением, оно может ухудшить ситуацию. В то время как пользователь, нажимающий кнопку «Продолжить» в диалоговом окне исключения, является сомнительным результатом, проглатывание исключений в глобальном обработчике исключений намного хуже.

Да, действительно ли пишут обработчик замены для ThreadException. Попросите его отобразить значение e.Exception.ToString () в окне сообщения, чтобы пользователь имел некоторое представление о том, что взорвалось. Затем отправьте электронное письмо или добавьте в журнал ошибок, чтобы вы знали, что пошло не так. Затем вызовите Environment.FailFast (), чтобы больше не было повреждений.

Сделайте то же самое для AppDomain.CurrentDomain.UnhandledException. Это не принесет больших тренировок.

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

8
ответ дан 6 December 2019 в 21:11
поделиться

Глобальная обработка исключений в приложении WinForms осуществляется с помощью двух обработчиков: Application.ThreadException и AppDomain.CurrentDomain.UnhandledException. ThreadException перехватывает необработанные исключения в основном потоке приложения, а CurrentDomain.UnhandledException перехватывает необработанные исключения во всех остальных потоках. Глобальная обработка исключений может быть использована для следующих целей: показ удобного сообщения об ошибке, регистрация трассировки стека и другой полезной информации, очистка, отправка отчета об ошибке разработчику. После перехвата необработанного исключения приложение должно быть завершено. Вы можете захотеть перезапустить его, но исправить ошибку и продолжить работу невозможно, по крайней мере, в нетривиальных приложениях.

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

1
ответ дан 6 December 2019 в 21:11
поделиться

Похоже, вам нужны аспекты. PostSharp может вам помочь.

1
ответ дан 6 December 2019 в 21:11
поделиться
Другие вопросы по тегам:

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