Глобальная исключительная ситуация в приложении WPF с Caliburn.Micro - PullRequest
6 голосов
/ 03 февраля 2011

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

http://www.codeproject.com/Articles/90866/Unhandled-Exception-Handler-For-WPF-Applications.aspx

Я использую Caliburn Micro в качестве фреймворка MVVM. Служба у меня во внешней сборке, и она вводится в класс модели представления с MEF.

Вот моя реализация для глобальной обработки исключений в приложении WPF.

App.xaml

         DispatcherUnhandledException="Application_DispatcherUnhandledException"
         Startup="Application_Startup"

Класс приложения:

public partial class App : Application
{
    private IMessageBox _msgBox = new MessageBoxes.MessageBoxes();

    public bool DoHandle { get; set; }

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

    private void Application_DispatcherUnhandledException(object sender,
                           System.Windows.Threading.DispatcherUnhandledExceptionEventArgs e)
    {
        if (DoHandle)
        {
            _msgBox.ShowException(e.Exception);
             e.Handled = true;
        }
        else
        {
            _msgBox.ShowException(e.Exception);
            e.Handled = false;
        }
    }


    void CurrentDomain_UnhandledException(object sender, UnhandledExceptionEventArgs e)
    {
        var ex = e.ExceptionObject as Exception;
        _msgBox.ShowException(ex);
    }


}

Метод обслуживания из внешней сборки:

    public void ServiceLogOn()
    {
        try
        {

        }
        catch (Exception ex)
        {

            throw ex;
        }
    }

Этот метод обслуживания вызывается в классе модели представления, например, при событии нажатия кнопки:

    [Export(typeof(ILogOnViewModel))]
    public class LogOnViewModel : Screen, ILogOnViewModel
    {
        public void LogOn()
        {
            _service.ServiceLogOn();
        }
    }
  1. Я запускаю приложение WPF в Visual Studio и выдаю исключение с сообщением «Неверные учетные данные» в методе ServiceLogOn.

    Я ожидаю, что вижу окно сообщения с исключением.

    Но Visual Studio останавливает отладку приложения и показывает исключение в методе службы в проекте службы.

  2. Поэтому я пытаюсь запустить WPF из exe-файла и вывести то же исключение в метод ServiceLogOn.

    Я получаю эту ошибку:

    Исключение было сгенерировано целью вызова.

Любое исключение из класса модели представления не обрабатывается в методах:

  • Application_DispatcherUnhandledException
  • или CurrentDomain_UnhandledException.

в классе приложений.

Чем я плохо занимаюсь?

Отредактировано с ответом Саймона Фокса.

Я пытаюсь реализовать в MEF совет по начальной загрузке Саймона Фокса, но я все равно что-то не так делаю. Я переместил логику дескриптора для исключения в метод OnUnhandledException в классе начальной загрузки.

Вот мой код из класса начальной загрузки:

 public class MefBootStrapper : Bootstrapper<IShellViewModel>
    { 
//...
    private IMessageBox _msgBox = new MessageBoxes.MessageBoxes();

    public bool DoHandle { get; set; }

    protected override void OnUnhandledException(object sender, System.Windows.Threading.DispatcherUnhandledExceptionEventArgs e)
    {
        if (DoHandle)
        {
            _msgBox.ShowException(e.Exception);
            e.Handled = true;
        }
        else
        {
            _msgBox.ShowException(e.Exception);
            e.Handled = false;
        }

    }
//...
    }

Я связываю некоторый метод из модели представления с кнопкой и выкидываю новое исключение. Примерно так:

public void LogOn()
{
    throw new ArgumentException("Bad argument");
}

Но результат - Сэм, я тестирую приложение из Visual Studio и получаю это исключение.

Исключение было сгенерировано целью вызова.

1 Ответ

16 голосов
/ 09 февраля 2011

Caliburn.Micro имеет встроенную поддержку для перехвата необработанных исключений.Класс Bootstrapper (который требуется для каждого проекта Caliburn) устанавливает его для вас и предоставляет метод virtual OnUnhandledException.

В вашем пользовательском BootStrapper вы должны override OnUnhandledException для выполнения любого пользовательскогодействия для необработанных исключений в вашем приложении.Обратите внимание, что вам, скорее всего, придется упорядочить действия, такие как отображение окна сообщения в потоке пользовательского интерфейса (Caliburn позволяет это легко с помощью Execute.OnUIThread).

У вас также может быть проблема в том, как ваша служба перемещает исключенияклиенту, но без каких-либо подробностей о том, как сервис реализован / размещен / и т.д., я не могу помочь.Вы используете WCF для SOAP?Используете ли вы FaultContracts ?

...