关闭SQLDataReaders - 如何判断它们是关闭的?(closing SQLDataRea

2019-09-17 02:46发布

我发现,我有一些网站连接池的问题,我跟踪下来的过程。 我知道一件事是寻找,以确保任何SQLDataReaders得到关闭,我虽然走了,并确保他们。 在我的头突然出现的一个问题是关于返回SQLDataReaders方法,以及它们如何得到关闭(或没有)。

因此,这里就是我有事情设置和一些示例方法:

public static SqlDataReader ExecuteReader(SqlCommand cmd)
{
    SqlConnection c = new SqlConnection(Properties.Settings.Default.DatabaseConn);
    cmd.Connection = c;
    c.Open();
    return cmd.ExecuteReader(System.Data.CommandBehavior.CloseConnection);
}

然后我有使用的方法“的ExecuteReader()”

public static SqlDataReader GetData()
{
  SqlCommand Query = new SqlCommand("select * from SomeTable");
  return ExecuteReader(Query);
}

现在说我有一个调用“的GetData”的另一种方法。 我简单的事情明显。

public static SqlDataReader GetMoreData()
{
  return GetData;
}

所以我的问题是,当我叫“GetMoreData”这样的

SqlDataReader dr = GetMoreData();
//do some stuff with 'dr'
dr.close();

都是我的SqlDataReaders和连接被正确关闭?

谢谢!

Answer 1:

描述

SqlDataReader实现IDisposable接口。 在每一个实现类IDisposable你应该叫Dispose或使用using ,以便腾出资源,在这种情况下关闭阅读器和底层连接。

IDisposable接口定义释放分配资源的方法。

样品

using(SqlDataReader dr = GetMoreData()) 
{
    try
    {   
       // do your stuff
    }
    catch(Exception ex)
    {
       // handle the exception
    }
} // the reader will get closed here

要么

SqlDataReader dr;
try
{   
    dr = GetMoreData();
    // do your stuff
}
catch(Exception ex)
{
   // handle the exception
}
finally
{
   // close the reader
   dr.Dispose();
}

编辑

通过JotaBe尼斯评论

但如果他实现了返回一个DataReader的方法,使用的应该是int方法的调用者使用。 因此,有没有办法保证的是,DataReader关闭。

我不建议返回一个SqlDataReader ,但如果你想做到这一点,你需要做的

SqlDataReader reader;
try
{
   reader = methodThatReturnsAReader();
}
catch(Exception ex)
{
   // handle the exception
}
finally
{
   // close the reader
   reader.Dispose();
}

更多信息

  • MSDN - IDisposable接口
  • MSDN - SqlDataReader类


Answer 2:

只要你确定dr.Close()被调用每次(即使在例外的情况下被抛出),然后是你的连接也将关闭。 然而,这是一般好的做法来包装类型的代码放到一个try / finally块,其中最后一个块包含dr.Close()语句。

另一种方法是使用一个语句,这需要通过SqlDataReader的实施IDisposable接口的优点。



Answer 3:

我建议你永远不会从方法返回一个DataReader。 你给关闭的DataReader方法调用者的责任。 如果方法调用者不保证该DataReader关闭,即使发生异常,就会有很大的麻烦。

当然,你不应该做这种方式。

什么是最糟糕的,在某些情况下,一个开放的DataReader可以在数据库中创建锁。

唯一的例外是,如果方法是私有的,你确保所有的调用者都关闭的DataReader。 但它仍然是相当容易出错。



Answer 4:

using的语句,缠SqlDataReader dr = GetMoreData()会保护你的,只要它在每一个地方的地方使用GetMoreData()被调用。 这是难以管理,这样可以更好地通过改变设计来保护自己。

从微软模式与实践 :

“使用时,下列条件为真一个DataSet:

- 你有缓存或层之间传递数据。”

和....相比:

“使用时,下列条件为真一个DataReader:

- 你有一个数据容器,比如一个业务组件,你可以把数据“。

我想说你的应用层并没有出现使用业务组件。 虽然这是事实,数据集有一个比的DataReader更大的开销,可以这样考虑:

  • 泄漏的连接(高,不可预测的)与使用数据集的成本的成本(可测量)
  • 有多少数据你需要-你可以返回DataTableDataRow ,而不是一个DataSet的?

的DataReader是伟大的低级别的代码,如数据访问组件,但不应该被你的应用程序的不同部分之间传来传去。



文章来源: closing SQLDataReaders - how to tell if they are closed?