DispatcherUnhandledException с библиотекой классов, вызываемой через Reflection - PullRequest
1 голос
/ 27 мая 2011

Загружаю библиотеку классов WPF MVVM с отражением. Мне также нужен обработчик исключений, как описано здесь .

Поскольку это размещенное приложение WPF, я не могу использовать App.xaml! Вот почему я реализовал все необходимое в классе, который загружает мое приложение, как объяснено здесь , в том числе:

Application.Current.DispatcherUnhandledException += new DispatcherUnhandledExceptionEventHandler(Current_DispatcherUnhandledException);

Проблема здесь в том, что когда я выкидываю исключение (из потока фонового работника, кстати), оно не работает хорошо. По сути, если я вручную выбрасываю исключение NullReferenceException, вызывая Dispatcher.Invoke (чтобы вызвать исключение в потоке пользовательского интерфейса), и когда я попадаю в отладчик Current_DispatcherUnhandledException, то исключение, которое я вижу, не является NullReferenceException, а представляет собой исключительное исключение TargetInvocation с сообщением «Исключение было сгенерировано целью вызова».

Я выяснил, что это исключение может быть вызвано методом invoke, который вызывает рефлексию WPF dll.

Похоже, что NullReferenceException перехватывается "методом вызова библиотеки классов WPF", перед приложением wpf ...

Это сводит меня с ума!

Пожалуйста, помогите!

1 Ответ

2 голосов
/ 03 августа 2011

NullReferenceException действительно перехватывается платформой WPF и включается в исключение TargetInvocationException. Исходное исключение NullReferenceException по-прежнему доступно в поле InnerException исключения TargetInvocationException.

Вот пример того, как извлечь исходное исключение:

public static void Main()
{
    Dispatcher mainThreadDispatcher = Dispatcher.CurrentDispatcher;

    mainThreadDispatcher.UnhandledException += new DispatcherUnhandledExceptionEventHandler(mainThreadDispatcher_UnhandledException);

    // Setup a thread that throws an exception on the main thread dispatcher.
    Thread t = new Thread(() =>
        {
            mainThreadDispatcher.Invoke(new Action(
                () =>
                {
                    throw new NullReferenceException();
                }));
        });

    t.Start();

    // Start the dispatcher on the main thread.
    Dispatcher.Run();
}

private static void mainThreadDispatcher_UnhandledException(object sender, DispatcherUnhandledExceptionEventArgs e)
{
    Exception targetInvocationException = e.Exception; // e.Exception is a TargetInvocationException
    Exception nullReferenceException = e.Exception.InnerException; // e.Exception.InnerException is the NullReferenceException thrown in the Invoke above
}
...