在C#数据库相关的类中使用和尝试catch?

时间:2015-07-01 13:08:45

标签: c# using

连接数据库时是否使用关键字catch或处理C#中的异常?或者我应该在使用中的所有数据库方法中使用try catch块?使用try catch是否会创建不必要的代码?

using (var db = new ApplicationContext())
{        
    try {
       /* Query something */
    } catch(Exception e) {
       logger.Debug(e);
    }
}  

5 个答案:

答案 0 :(得分:8)

using块没有"处理"对您而言,它只会确保在Dispose()对象(在本例中为您的IDisposable实例)上调用db方法,即使发生异常也是如此。所以,是的,您需要在需要的地方添加try-catch块。

这就是说,一般来说,你只想捕捉异常,你可以用它们来实际做一些有意义的事情。如果您只需要记录异常,请考虑在调用堆栈中较高的位置执行异常处理,这样您就不必在整个地方使用try-catch块来丢弃代码。

您可以阅读有关using Statement here的内容,了解其实际功能及其翻译方式。

修改

如果出于某种原因,你选择将你的try-catch块保持在原来的位置,至少要确保重新抛出异常,而不是吞下它,这就像把地毯扫到地毯下一样并假装一切都很好。此外,请务必重新抛出它而不会丢失宝贵的堆栈跟踪。像这样:

using (var db = new ApplicationContext())
{        
    try {
       /* Query something */
    } catch(Exception e) {
       logger.Debug(e);
       throw; // rethrows the exception without losing the stack trace.
    }
}

编辑2 :Eric Lippert关于exception handling的非常好的博客文章。

答案 1 :(得分:8)

  

连接数据库时是否使用关键字catch或处理C#中的异常?

using在逻辑上等同于try-finally,所以是的,它处理异常,但它不会停止异常。 finally传播异常。

  

我应该在使用中的所有数据库方法中使用try catch块吗?

即可。 try-catch应该在外面 using。这样就可以保护资源的创造。

  

使用try catch是否会创建不必要的代码?

我不知道这个问题意味着什么。

你没有问过一些问题:

  

我是否应该捕获所有日志记录的异常,然后重新抛出它们?

即可。只捕捉并吃掉你知道如何处理的异常。如果你想记录异常,那么当你完成记录时,重新抛出它们;其他代码可能想要处理它们。

  

编写此代码的正确方法是什么?

分开您的疑虑。你有三个问题:

  • 处置资源
  • 记录所有例外
  • 处理预期的外生异常

每一项都应该由一份单独的声明来处理:

try // handle exogenous exceptions
{  
   try // log all exceptions
   {
       using(var foo = new Foo()) // dispose the resource
       {
           foo.Bar();
       }
   }
   catch(Exception x)
   {
       // All exceptions are logged and re-thrown.
       Log(x);
       throw;
   }
}
catch(FooException x) 
{
    // FooException is caught and handled
}

如果您的目标是仅记录未处理的异常,则反转两个处理程序的嵌套,或使用其他机制,例如appdomain的未处理异常事件处理程序。

答案 2 :(得分:3)

您的using将由C#编译器转换为底部代码,8.13 The using statement

{
    var db = new ApplicationContext();
     try
     {
       try {
          /* Query something */
       } catch(Exception e) {
          logger.Debug(e);
       }
     }
     finally
     {
       // Check for a null resource.
       if (db!= null)
        // Call the object's Dispose method.
           ((IDisposable)myRes).Dispose();
     }
}

所以,我的意见,对于你的情况,我认为没有using陈述会更好,它会有点清晰,步骤会更少:

 var db = new ApplicationContext();
 try
 {
    /* Query something */                  
 }
 catch(Exception e)
 {
    logger.Debug(e);
 }
 finally
 {
    if (db!= null)
    {
      ((IDisposable)myRes).Dispose();
    }
 }

因为using它只是一种语法糖。

P.S:try语句的性能成本非常小,您可以将代码保留原样。

答案 3 :(得分:1)

使用using关键字在块完成后,使用参数内的对象(在本例中为上下文)被正确处理,因此,您仍然需要使用try-catch关键字来处理异常

答案 4 :(得分:1)

由于using不处理任何异常,您可能需要交换。

usingtry-finally的语法糖,所以你知道,即使没有在构造函数上处理异常,连接也将被关闭或根本不建立。

try {
    using (var db = new ApplicationContext())
    {        

       /* Query something */

    }  
} catch(Exception e) {
   logger.Debug(e);
}