Я занимаюсь разработкой облегченного WPF MVVM-фреймворка и хотел бы иметь возможность отлавливать необработанные исключения и в идеале восстанавливаться после них.
На данный момент игнорируя все веские аргументы в пользу того, чтобы этого не делать, я сталкиваюсь со следующей ситуацией:
Если я зарегистрирую обработчик для AppDomain.CurrentDomain.UnhandledException в методе OnStartup файла App.xaml.cs, как показано ниже ...
App.xaml.cs:
protected override void OnStartup(StartupEventArgs e)
{
AppDomain.CurrentDomain.UnhandledException += new
UnhandledExceptionEventHandler(this.AppDomainUnhandledExceptionHandler);
base.OnStartup(e);
}
void AppDomainUnhandledExceptionHandler(object sender, UnhandledExceptionEventArgs ea)
{
Exception e = (Exception)ea.ExceptionObject;
// log exception
}
и затем вызвать исключение в одной из моих виртуальных машин, обработчик вызывается, как и ожидалось.
Пока все хорошо, за исключением того факта, что я не могу восстановить с помощью этого подхода, все, что я могу сделать, - записать исключение и затем позволить CLR завершить приложение.
Что я на самом деле хотел сделать, так это восстановить и вернуть управление основной виртуальной машине. (Опять откладывая мотивы против этого).
Итак, читая, я решил зарегистрировать обработчик событий для AppDomain.CurrentDomain.UnhandledException в том же месте, чтобы код теперь выглядел примерно так ...
protected override void OnStartup(StartupEventArgs e)
{
AppDomain.CurrentDomain.UnhandledException +=
new UnhandledExceptionEventHandler(this.AppDomainUnhandledExceptionHandler);
this.DispatcherUnhandledException +=
new DispatcherUnhandledExceptionEventHandler(DispatcherUnhandledExceptionHandler);
base.OnStartup(e);
}
void AppDomainUnhandledExceptionHandler(object sender, UnhandledExceptionEventArgs ea)
{
Exception e = (Exception)ea.ExceptionObject;
// log exception
}
void DispatcherUnhandledExceptionHandler(object sender, DispatcherUnhandledExceptionEventArgs args)
{
args.Handled = true;
// implement recovery
}
Проблема заключается в том, что как только я регистрирую обработчик для этого. DispatcherUnhandledException НИКОГДА НЕ ВЫЗЫВАЕТСЯ ХЕНДЛЕР. Поэтому регистрация DispatcherUnhandledExceptionHandler каким-то образом деактивирует обработчик для AppDomain.CurrentDomain.UnhandledException.
Есть ли у кого-нибудь подход для перехвата и восстановления после необработанных исключений ВМ?
Может быть важно упомянуть, что в фреймворке нет явного использования многопоточности.