【问题标题】:Adding further exception handling to an application with a single exception handler使用单个异常处理程序向应用程序添加进一步的异常处理
【发布时间】:2011-09-15 16:39:24
【问题描述】:

我刚刚使用

制作了一个桌面应用程序

技术:

  • MEF
  • EF
  • WinForms

模式:

  • MVVM
  • IOC
  • 工作单位
  • 存储库模式

现在我需要添加异常处理机制,目前我的应用程序除了在 Main() 之外没有任何 try catch。我把try catch放在哪里,并在全局异常处理程序(ApplicationThreadException)中处理所有类型的异常。但这不是处理异常的正确方法。

那么有什么想法或任何库或任何可以帮助我处理异常的东西吗?

【问题讨论】:

  • 就是这样,为什么不合适?
  • @orn:你认为这种方法是正确的吗?
  • 是的,我正在考虑下面@Maxim 的答案,全部捕获并在需要时尝试捕获,如果没有,它们会冒泡

标签: .net winforms design-patterns exception-handling


【解决方案1】:

所以任何想法或任何图书馆或任何可以帮助我处理的东西 异常?

我认为你正试图在众所周知的马逃跑后关上谷仓的门。

异常处理不是事后才可以轻易添加的。在构建应用程序时应考虑异常处理。对于您编写的每个功能代码单元,您应该仔细考虑是否可以生成异常,如果可以,请确定处理它们的适当位置。当然,没有什么魔法库可以随便插入。

现在我需要添加异常处理机制,目前我的 除了在 Main() 中,应用程序在任何地方都没有 try catch。我放在哪里 try catch,并处理了全局异常中的所有类型异常 处理程序(应用程序线程异常)。但这不是正确的方法 处理异常。

在捕获main 中的所有异常时,您(到目前为止)已决定您的应用不需要在任何其他级别处理它们。真的是这样吗?问问你自己,你的应用程序当前是否运行良好,并且在没有不断出错的情况下完成了它应该做的事情。 真的需要添加所有异常处理代码吗?

  • 如果您的应用程序现在运行良好并且您没有发现任何问题,那么答案可能是否定的:您已经获得了当前需要的所有异常处理。

  • 但是,如果您的应用程序有错误并且经常失败,并且在 main() 中捕获了一些异常或其他情况,并且您认为整个应用程序不应该仅仅因为可恢复的错误而失败,那么您已经在其他地方确定了异常处理案例,您应该返回并确定个别失败案例并在您的应用中的适当级别解决它们。

【讨论】:

  • ,你说得对,脱帽致敬。实际上由于一些时间限制,我无法在开发应用程序时找到实现正确异常处理的方法。我想再分享一点,将来这个应用程序将具有通过电子邮件发送错误报告和屏幕截图等功能,所以想要一些设计参考,想看看在企业应用程序中如何处理异常。所以从参考我可以找到我的方式,再次感谢。
  • 它应该是您编写的每个功能代码单元的一部分。 哎呀。不能少同意。我发现很少有代码单元需要任何异常处理。我将异常处理代码放在几个战略点。我写的 90% 或更多的方法只是让他们的异常冒泡到这些点之一。只有在我编写了大量违反 SRP 的大型方法时,您的声明才对我有效。
  • @Charles:+1 谢谢。我已经编辑了我的副本以反映这种情绪,因为这就是我的意思。我并不是要建议每一小块代码都有一个异常处理程序,而是需要考虑异常处理并在编写代码时在适当的地方实现它,而不是在最后被固定.
  • 如果您的应用程序现在运行良好并且您没有发现任何问题,那么答案可能是否定的:您已经获得了当前需要的所有异常处理。 i> 我或多或少同意这一点,但这与你之前所说的相矛盾。我也同意这匹马已经狂奔了。异常处理是开发的一个方面,我发现事后添加它并不是特别困难。但是,这确实需要从编写好的 SOLID 代码开始。
  • 好的,你在我写最后一条评论时所做的编辑使该评论的前半部分过时了(你不再自相矛盾了)。好的! :) (+1)
【解决方案2】:

只有你的应用程序的操作逻辑告诉你在哪里使用 try/catch。

如果您可以在异常情况下做某事 - 那么您将声明放在那个点上。如果在整个应用程序中您觉得不需要异常处理,因为您根本无法使用它们 - 最外层的捕获器是您处理异常的好地方,但仅用于日志记录目的。

【讨论】:

    【解决方案3】:

    连接事件处理程序以处理应用程序中任何地方的未处理异常,然后不要在 main 中使用 try/catch。

    在你的 Main() 中试试这个:

        //Wire up handling of all unhandled exceptions
        AppDomain.CurrentDomain.UnhandledException += CurrentDomain_UnhandledException;
        Application.ThreadException += new System.Threading.ThreadExceptionEventHandler(Application_ThreadException);
        Application.SetUnhandledExceptionMode(UnhandledExceptionMode.CatchException);
    
        //Handle the events
        static void Application_ThreadException(object sender, System.Threading.ThreadExceptionEventArgs e)
        {
            HandleException(e.Exception);
        }
    
        static void CurrentDomain_UnhandledException(object sender, UnhandledExceptionEventArgs e)
        {
            HandleException((Exception)e.ExceptionObject);
        }
    
        public static void HandleException(Exception e)
        {
             //Do something with the exception stored in e.
             //Email an admin, show the user a pretty message, show the user a detailed stack trace only if they click Show Details, etc.  
    
        }
    

    【讨论】:

    【解决方案4】:

    我总是使用这个代码:

    public static void HandleException(Exception  e)
            {
                string s="Message= "+e.Message +"\n";
                s+="Source= "+e.Source +"\n";
                s+="Stack Trace= "+e.StackTrace+"\n";
                Exception inner=e.InnerException;
                MessageBox.Show(s);
                while(inner !=null)
                {
                    string ss="Message= "+inner.Message +"\n";
                    ss+="Source= "+inner.Source +"\n";
                    ss+="Stack Trace= "+inner.StackTrace+"\n";
                    MessageBox.Show(ss);
                    inner=inner.InnerException;
    
    
                }
            }
    

    【讨论】:

      【解决方案5】:

      你的方法肯定是不合适的,因为你在距离抛出点很远的地方捕获了异常。并且您的全局捕获最终可以记录但无法做出反应。

      想象一下在操作之前尝试在某个文件夹中创建文件的情况,如果该文件夹不存在并且您首先创建文件夹然后在其中创建文件,您可能决定捕获异常。在 Main 方法中为时已晚,因为您无法执行任何操作,您可以登录 yes 但无法创建文件夹,即使您这样做了,程序也不会从正确的位置继续。

      这是关于为什么要进行适当的异常处理的非常模糊的介绍,只是众多示例中的一个......只需将您的 try catch 放在任何需要的地方,然后对异常做出反应(处理它们)或抛出它们(有时从内部catch。有时会完全省略 catch 子句)...我认为您应该阅读一些关于此的文章。

      【讨论】:

      • 感谢分享信息。其实我在想办法,但找不到,我看了很多文章。但我不满意,这意味着事情已经过去了,你能给我网址以供参考吗?我坚持这一点。
      • -1:请澄清只有在有办法实际处理异常时才应捕获异常。我担心阅读本文的人会认为您的意思是他们要在程序的每个点捕获异常,这肯定不是您要说的。
      • 请再读一遍,我说在某些情况下你省略了 catch 意思就是你所说的。如果它有意义,或者你什么都不做,或者你做其他事情,你就会明白......我听着很清楚
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-05-01
      • 2014-05-04
      • 2012-09-05
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多