使用 Caliburn.Micro 的 WPF 应用程序中的全局处理异常

发布于 2024-10-15 20:43:42 字数 3375 浏览 3 评论 0原文

您好,我尝试在我的 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. 我在 Visual Studio 中运行 WPF 应用程序,并在 ServiceLogOn 方法中生成带有消息“错误凭据”的异常.

    我希望看到有异常的消息框。

    但是 Visual Studio 停止调试应用程序并在服务项目中的服务方法中显示异常。

  2. 因此,我尝试从 exe 文件运行 WPF 并在 ServiceLogOn 方法中产生相同的异常。

    我收到此错误:

    调用目标已引发异常。

视图模型类中的任何异常都不会在方法中处理:

  • Application_DispatcherUnhandledException
  • 或 CurrentDomain_UnhandledException。

在应用程序类中。

我做什么坏事了?

用 Simon Fox 的答案进行了编辑。

我尝试在 Simon Fox 的 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");
}

但结果是 sam,我在 Visual Studio 中测试应用程序并得到此异常。

调用目标已引发异常。

Hi I try implement solution from this site im my WPF app for global exception handling.

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

I use Caliburn Micro as MVVM framework. Service I have in external assembly and it is injected in view model class with MEF.

Here is my implementation for global exception handling in WPF app.

App.xaml

         DispatcherUnhandledException="Application_DispatcherUnhandledException"
         Startup="Application_Startup"

App class:

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);
    }


}

Service method from external assembly:

    public void ServiceLogOn()
    {
        try
        {

        }
        catch (Exception ex)
        {

            throw ex;
        }
    }

This service method is call in view model class for example on button click event:

    [Export(typeof(ILogOnViewModel))]
    public class LogOnViewModel : Screen, ILogOnViewModel
    {
        public void LogOn()
        {
            _service.ServiceLogOn();
        }
    }
  1. I run WPF app in Visual Studio and produce exception with message "Bad credentials" in ServiceLogOn method.

    I expect that I see the message box with the exception.

    But Visual Studio stop debuging app and show exception in service method in service project.

  2. So I try run WPF from exe file and produce same exception in ServiceLogOn method.

    I get this error:

    Exception has been throw by target of an invocation.

Any exception from view model class is not handled in methods:

  • Application_DispatcherUnhandledException
  • or CurrentDomain_UnhandledException.

in App class.

What I do bad?

EDITED with Simon Fox’s answer.

I try implement in MEF bootstraper advice of Simon Fox’s, but I still something do wrong.
I move handle logic for exception to OnUnhandledException method in bootstraper class.

Here is my code from bootstraper class:

 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;
        }

    }
//...
    }

I bind some method from view model on button and throw new exception. Something like this:

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

But result is sam, I test app out of Visual Studio and get this exception.

Exception has been throw by target of an invocation.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

自由如风 2024-10-22 20:43:42

Caliburn.Micro 内置了对挂钩未处理异常的支持。 Bootstrapper 类(每个 Caliburn 项目都需要)会为您进行设置并提供 virtual OnUnhandledException 方法。

在自定义 BootStrapper 中,您必须重写 OnUnhandledException 才能对应用中未处理的异常执行任何自定义操作。请注意,您很可能必须编组操作,例如向 UI 线程显示消息框(Caliburn 通过 Execute.OnUIThread 轻松启用此功能)。

您的服务将异常转移到客户端的方式也可能存在问题,但如果没有有关服务如何实现/托管/等的任何详细信息,我无法提供帮助。你用WCF做SOAP吗?您是否使用FaultContracts

Caliburn.Micro has built in support for hooking unhandled exceptions. The Bootstrapper class (which every Caliburn project requires) sets this up for you and provides the virtual OnUnhandledException method.

In your custom BootStrapper you must override OnUnhandledException to perform any custom actions for unhandled exceptions in your app. Note that you will most likely have to marshal actions such as displaying a message box to the UI thread (Caliburn enables this easily via Execute.OnUIThread).

You may also have an issue in the way your service moves exceptions to the client, but without any details of how the service is implemented/hosted/etc I cannot help. Are you using WCF to do SOAP? Are you using FaultContracts?

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文