正确使用try / catch块中的finally子句

时间:2014-05-06 17:56:07

标签: c# exception try-catch

我试图找出最好的"方法在我的sql数据访问层方法中执行(close)语句。

我想知道这两种方式中的哪一种更正确(谢谢):

选项#1

public void dbOperation( ... )
{
    try
    {
        _cmd.Open();        
        _cmd.Execute();
    }
    catch (Exception ex)
    {
        throw ex;       
    }
    finally
    {
        _cmd.Close()
    }   
}

选项#2

public void dbOperation( ... )
{
    try
    {
        _cmd.Open();        
        _cmd.Execute();
    }
    catch (Exception ex)
    {
        _cmd.Close()    
        throw ex;   
    }

    _cmd.Close();
}

3 个答案:

答案 0 :(得分:9)

两者都不正确。你不应该只有一个catch子句来重新抛出异常,清除它的堆栈跟踪,并且什么都不做,这是你的第一个选择。

你应该只是关闭finally:

try
{
    _cmd.Open();        
    _cmd.Execute();
}
finally
{
    _cmd.Close()
} 

您的第二个代码段也有同样的问题,因为您不正确地重新抛出异常。

最好的选择是使用using,这只是一个尝试/最终没有捕获的语法糖:

using(var command = ...)
{
    command.Open();        
    command.Execute();
}

这还有一个额外的好处,即确保命令的范围与使用它的有效时完全相同。 try / finally块要求命令在被处理后成为有效的标识符。

答案 1 :(得分:2)

选项#1是两者中唯一正确的一个。事实上,您可以使用更少的代码获得相应的选项#1:

try
{
    _cmd.Open();        
    _cmd.Execute();
}
finally
{
    _cmd.Close()
}

如果抛出异常,则不需要catch块来重新抛出它。如果您想在catch块中执行某些操作,例如记录异常,请务必执行以下操作:

try
{
    _cmd.Open();        
    _cmd.Execute();
}
catch (Exception ex)
{
    logException(ex);
    throw;  //Just say throw, not throw ex, to preserve the original stack trace
}
finally
{
    _cmd.Close()
} 

答案 2 :(得分:-1)

选项#1。如果使用option2,除非它抛出异常,否则不会执行cmd.close