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



我试图找出"最佳"方式执行(关闭)语句在我的sql数据访问层方法。

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

选项# 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();
}

都不对。您不应该让catch子句再次重新抛出异常,清除其堆栈跟踪,而不做任何有意义的事情,这是您的第一个选项所做的。

你应该只是结束在finally:

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

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

最好的选择是使用using,它只是一个没有catch的try/finally的语法糖:

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

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

选项#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()
} 

选项#1。如果你使用option2,你将不会执行cmd。关闭,除非抛出异常

最新更新