C# 关闭SQLDataReaders-如何判断它们是否已关闭?
我发现我有一些网站连接池的问题,我在跟踪他们的过程中。我知道要寻找的一件事是确保任何SQLDataReader都被关闭,我已经检查并确保它们被关闭。我脑海中突然出现的一个问题是关于返回SQLDataReaders的方法以及它们如何关闭(或不关闭) 下面是我如何进行设置和一些示例方法:C# 关闭SQLDataReaders-如何判断它们是否已关闭?,c#,database-connection,connection-pooling,sqldatareader,C#,Database Connection,Connection Pooling,Sqldatareader,我发现我有一些网站连接池的问题,我在跟踪他们的过程中。我知道要寻找的一件事是确保任何SQLDataReader都被关闭,我已经检查并确保它们被关闭。我脑海中突然出现的一个问题是关于返回SQLDataReaders的方法以及它们如何关闭(或不关闭) 下面是我如何进行设置和一些示例方法: public static SqlDataReader ExecuteReader(SqlCommand cmd) { SqlConnection c = new SqlConnection(Propert
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()的方法”
现在假设我有另一个调用“GetData”的方法。我显然简化了事情
public static SqlDataReader GetMoreData()
{
return GetData;
}
所以我的问题是,当我像这样调用“GetMoreData”时
SqlDataReader dr = GetMoreData();
//do some stuff with 'dr'
dr.close();
我所有的SqlDataReader和连接都正确关闭了吗
谢谢 描述
SqlDataReader
实现了IDisposable
接口。
在每个实现了IDisposable
的类上,您应该调用Dispose
或使用using
为了释放资源,在本例中关闭读卡器和底层连接
IDisposable接口定义了释放已分配资源的方法
样品
或
SqlDataReader dr;
try
{
dr = GetMoreData();
// do your stuff
}
catch(Exception ex)
{
// handle the exception
}
finally
{
// close the reader
dr.Dispose();
}
编辑
JotaBe的评论不错
但是如果他实现了一个返回DataReader的方法,那么应该在该方法的调用方中使用using。因此,无法保证DataReader已关闭
我不建议返回SqlDataReader
,但是如果您想这样做,您需要这样做
SqlDataReader reader;
try
{
reader = methodThatReturnsAReader();
}
catch(Exception ex)
{
// handle the exception
}
finally
{
// close the reader
reader.Dispose();
}
更多信息
另一种选择是using语句,它利用SqlDataReader实现的IDisposable接口。我建议您永远不要从方法返回DataReader。您将关闭DataReader的责任交给方法调用方。如果方法调用方不能确保DataReader已关闭,即使发生异常,您也会遇到严重的问题 当然,你不应该这样做。 最糟糕的是,在某些情况下,开放式DataReader可以在数据库中创建锁
唯一的例外是,如果方法是私有的,并且您确保所有方法调用方都在关闭DataReader。但是它仍然很容易出错。围绕
SqlDataReader dr=GetMoreData()
的using
语句将保护您,只要它在调用GetMoreData()
的每个地方都使用。这很难管理,因此您可以通过更改设计来更好地保护自己
发件人:
“在下列条件为真时使用数据集:
-您必须在层之间缓存或传递数据。”
与之相比:
“当下列条件为真时,使用数据读取器:
-您有一个数据容器(如业务组件),可以将数据放入其中。”
我想说的是,您的应用程序有层次,似乎没有使用业务组件。虽然数据集比数据存储器有更大的开销,但请考虑如下:
- 泄漏连接的成本(高,不可预测)与使用数据集的成本(可测量)
- 您需要多少数据-是否可以返回
或DataTable
而不是数据集DataRow
DataReader适用于低级代码,如数据访问组件,但不应在应用程序的不同部分之间传递。您说“全部”,但您只有一个阅读器和一个连接。从你的代码来看,如果没有抛出异常,当读卡器关闭时,这两个部分都应该关闭。如果你的
//使用'dr'执行一些操作部分抛出异常,那么,不,你的读卡器没有正确关闭。dknaack的回答通过告诉您使用using
语句修复了这个bug。我发现您使用的是静态函数。在实际代码中不使用任何静态字段来放置读取器或连接,是吗?是的,这是正确的,但如果他实现了一个返回DataReader的方法,则应该在该方法的调用方中使用using。因此,无法保证DataReader已关闭。这是一个设计缺陷!
SqlDataReader dr;
try
{
dr = GetMoreData();
// do your stuff
}
catch(Exception ex)
{
// handle the exception
}
finally
{
// close the reader
dr.Dispose();
}
SqlDataReader reader;
try
{
reader = methodThatReturnsAReader();
}
catch(Exception ex)
{
// handle the exception
}
finally
{
// close the reader
reader.Dispose();
}