2011-11-22 36 views
5

因此,我最近正在编写一个用C#编写的相对复杂的应用程序,它可以反复执行一系列小任务。当我第一次启动应用程序时,我意识到我输入的很多代码都是重复的,所以我开始将大部分应用程序逻辑封装到单独的帮助器类中,我可以根据需要调用它们。哪里是我的C#应用​​程序中处理异常的正确位置?

不用说我的应用程序(和代码量)的大小,切成两半。但是当我经历的时候,我注意到我的应用程序中有其他东西似乎是重复的,看起来好像可以改进。

现在大部分的我在我的辅助类方法或者作出HttpWebRequest或执行保存/上的文件删除操作。话虽如此,我需要处理最终调用不会完成的可能性,或者因为没有足够的空间或文件而导致文件无法保存。我遇到的问题是每次调用其中一种方法时,必须不断写入try/catch语句。最重要的是,我必须重新输入错误信息(或者最终是状态信息,我想知道它何时成功)。

所以这里有种类的片断的我有什么类型:

try 
    { 
    ItemManager.SaveTextPost(myPostItem); 
    } 
    // Majority of the time there is more than one catch! 
    catch 
    { 
    //^^^Not to mention that I have to handle multiple types of exceptions 
    //in order to log them correctly(more catches..ugh!) 
    MessageBox.Show("There was an error saving the post."); 
    //Perform logging here as well 
    } 

从我迄今得出的结论是:

  • 对我来说,这是矫枉过正有超过50写次我的应用程序。 听起来像我应该包括在助手类和 包括全套捕获。
  • 但我怎么知道结果呢?我可能想要返回包含错误/成功消息的 字符串。
  • 真正为这些类型的方法不需要从辅助方法被称为从方法到其封装在一个try/catch块。

是这种做法是否正确?有没有另外一种方法呢?我应该在调用方法中使用try/catch吗?由于这是我的第一枪,我真的很想听听处理这个场景的其他人是怎么说的。

+0

最近有一个类似的问题被问到最近:http://stackoverflow.com/questions/8156530/exception-handling-in-method-definition-or-call/8156574#8156574 – Tudor

回答

1

我觉得把try/catch语句在您所呼叫的方法是完全正常的。您可以通过多种方式将错误/成功代码返回给调用代码。 .NET和c#很好地处理枚举,所以你可以有ItemManager.SaveTextPost(myPostItem, out errorCode);其中errorCode将是一个枚举值,让你知道是否有任何问题发生。它也可以简单到只要方法成功返回bool true,否则返回false。还有,你可以处理这个问题,但就我而言,把在该方法中的try/catch是做事的可取的方法很多方法。

+0

+1发送回枚举值。我认为这是一个好主意。不知何故,我知道有一种比发送字符串更好的方法哈哈。 – loyalpenguin

+0

我不会用'SaveTextPost(myPostItem,out errorCode)'方式去。使用代码的人可能会感到困惑,并且通过枚举错误值来维护会更加痛苦。此外,是否也不是用来处理错误的例外?如果'true'和'false'对你来说足够了,返回一个布尔值是可以的。 – Otiel

+0

异常是出于错误,但不应该依赖为每个错误抛出一个。任何你期望会出错的东西都应该被妥善处理,其他任何异常情况都应该抛出一个异常(完美的例子就是处理文件系统IO - 你不知道文件处于什么状态以及其他进程可能处理的东西在上面)。抛出异常是很昂贵的,在我看来,使用它们代替防御性编程实践只是不好的编码。 –

1

AOP库,例如PostSharp旨在处理横切关注点完全一样。

如果所有这些辅助方法采用相同的样板尝试捕捉 - >处理多种类型的异常,那么你可以写一个方面,做的是,和装饰的所有相关方法与适当的属性。

1

有异常处理没有单一的完美的规则,所以答案是:这要看情况。一般来说,如果你知道如何处理它们,你只应该捕捉异常。在你的例子中,我的第一个问题是,如果应用程序可以在这个错误之后继续运行并且仍然处于有效状态。如果不是,则应在登录后重新抛出异常。然后考虑嵌套异常:您可以捕获异常,通过将其嵌套到另一个异常并添加该异常来添加信息。如果你仔细设计你的异常类和处理程序,你的日志和显示代码应该比你期望的简单得多。但细节显然取决于您的应用程序。

1

通过检查if块,你应该抛出异常,如果每个参数都是正确的,每个文件都是可以访问的......然后如果需要,在你的帮助器方法中实现一些try catch块并在捕获时抛出异常。

最后,附上由try catch块,这些辅助方法,但在这个时候,真的捕获异常:

try 
{ 
    ItemManager.SaveTextPost(myPostItem); 
    // SaveTextPost can throw some exceptions (that you know) 
} 
catch (Exception e) 
{ 
    // You know the exceptions that SaveTextPost can return, so threat them 
    // correctly 
    if (e is FileNotFoundException) 
     MessageBox.Show("The file was not found when saving the post."); 
    else if (e is ArgumentNullException) 
     MessageBox.Show("The post can't be null to be saved."); 
    else 
     MessageBox.Show("There was an error saving the post."); 
} 

最后,你需要把错误并表现出错误消息给用户。您只能决定是否应该在助手方法或调用辅助方法的类中实现MessageBox.Show
就我个人而言,我认为帮助程序方法注定会被任何开发人员用来运行您的代码,所以您应该让他决定他想要处理的错误。这意味着在辅助方法中抛出异常。

+0

是的,但如果你调用的方法已经处理了可能的异常,那么这个方法的目的就是将方法封装在try/catch块中。说实话,我有点想摆脱这一点。我想有99.9%的几率可能会失败... – loyalpenguin

+0

+1我不知道你可以确定这种异常的类型。学到东西了。我明确同意,开发人员选择沟通信息的方式(有时从不)应该留给他们。 – loyalpenguin

+2

这种类型的比较不适用于你想要做的事情..需要像if(e是FileNotFoundException){} – iamkrillin

0

我个人采取的异常处理..添加try {} catch {}下才有意义。

例如,在调用“不可信”代码(即模块或插件)时总是使用try catch。否则,如果你要捕捉异常,确保你可以对它做一些有意义的事情。如果不是,允许例外冒泡到你可以的地步。

还有比尝试调试应用程序,其中开发人员捕获的异常,并返回一个布尔值更糟糕的几件事情。只是说'

1

Try/Catch是一个很好的解决方案。一个建议,我喜欢用它来阻止错误的流程:异常捕获: 尝试 { } catch(Exception ex) { ShowExceptionError(ex); } 然后,我将简单地将所有异常抛出到单个方法,并让该方法处理每个异常。

像这样的:

private void ShowExceptionError(ex) 
{ 
    string errorMessage = "Type of error:" + ex.GetType().ToString(); 
    string stackTrace = ex.StackTrace(); 
    MessageBox.Show(errorMessage + "\n\n" + stackTrace); 
} 
1

所有这些方面都是非常好的选择。你不想做的一件事就是使用try {} catch {}来控制流量。这意味着类似这样的事情(再次避免这种情况)

Void SomeMethod() 
{ 
    try 
    { 
     while(somecondition) 
     { 
      try 
      { 
      } 
      catch (Exception ex) 
      { 

      } 
      } 
    } 
    catch (Exception ex) 
    { 
      ..... 
    } 

而是你想防守地编码。

相关问题