2012-05-31 5 views
6

Я пытаюсь создать простой глобальный обработчик исключений в приложении WPF, который создается с помощью MVVM Light Toolkit, но мне сложно с ним работать.Глобальный обработчик исключений для приложения MVVM Light

Дело в том, что исключение Поднялся в модели представления не будет пойман в обработчике UnhandledException экране приложения, даже если я зарегистрировать прослушиватель как Dispatcher и AppDomain, как это:

private void Application_Startup(object sender, StartupEventArgs e) 
{ 
    AppDomain.CurrentDomain.UnhandledException += DomainUnhandledException; 
    DispatcherUnhandledException += App_DispatcherUnhandledException; 
} 

private void DomainUnhandledException(object sender, UnhandledExceptionEventArgs unhandledExceptionEventArgs) 
{ 
    var exception = unhandledExceptionEventArgs.ExceptionObject as Exception; 
    ShowExceptionMessage(exception); 
} 
private void App_DispatcherUnhandledException(object sender, DispatcherUnhandledExceptionEventArgs e) 
{ 
    ShowExceptionMessage(e.Exception); 
    e.Handled = true; 
} 

я нашел this blog post, который описывает проблему пятна на, с решением, описанным с этим кодом отрезал для просмотра моделей:

// Throw the exception in the UI thread. 
App.Current.RootVisual.Dispatcher.BeginInvoke(() => { throw new MyException(); }); 

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

Итак, вопрос: возможно ли повторное бросить исключения из других потоков в поток пользовательского интерфейса в одном месте?

Обновление: Добавлен более подробный код для установки обработчика событий приложения.

+0

Извините, но я, очевидно, недостаточно исследовал эту проблему, прежде чем задавать вопрос. Исключение, которое я тестировал, фактически выбрано в конструкторе VM. Unity используется для DI, поэтому может возникнуть вопрос, как обрабатывать исключения в конструкторах на объектах, создаваемых единством? – Anttu

+0

Чтобы объяснить немного далее, так как виртуальные машины привязаны к DataContext представления: DataContext = {{Binding MyVm, Source = {StaticResource Locator}} "'. Локатор раскрывает следующее свойство: 'public MyViewModel MyVm {get {return unityContrainer.Resolve (); }} ' – Anttu

ответ

4

Я думаю, что понять это сейчас.

Проблема связана с тем, что WPF подавляет исключения, в привязки данных в целях, и потому, что на мой взгляд модель привязки данных к представлению в DataContext (через свойство в моем используя инжектором единство зависимости ViewModelLocator) каких-либо исключений в построение модели обзора будет проглочено.

См. this SO question для получения дополнительной информации.

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

+0

Они только подавляются, как только вид уже виден. Если вы попытаетесь показать представление, и модель представления имеет исключения, созданные его связанными свойствами (предположив, что вы уже установили контекст данных перед вызовом show), вы не сможете открыть окно –

1

«Глобальные» события обработки исключений для приложений WPF и Windows Forms (Application.DispatcherUnhandledException и Application.ThreadException) срабатывают только для исключений, создаваемых в основном потоке пользовательского интерфейса. Вы по-прежнему должны обрабатывать исключения из рабочих потоков вручную.

AppDomain.CurrentDomain.UnhandledException запускает любое необработанное исключение, но не предоставляет никаких средств для предотвращения закрытия приложения после этого.

  • Возможно также проверить объединение потоков «разделяй и властвуй».
  • TPL

How do I invoke a method on the UI thread when using the TPL?

+0

Да, я знаю, что DispatcherUnhandledException для исключений потоков пользовательского интерфейса и UnhandledException AppDomain для любого необработанного исключения.Дело в том, что никто из них не ловит никакого исключения, которое я поднимаю в обработчике команд в виртуальной машине. У MVVM Light есть своего рода «глобальный обработчик исключений» для его потоков, или мне нужно обернуть все обработчики команд в блок try-catch? – Anttu

+0

На самом деле, если я сделаю исключение в команде с привязкой к данным, он действительно превратится в обработчик исключений Диспетчера. См. Мой комментарий по вопросу. – Anttu

Смежные вопросы