【发布时间】:2008-10-20 18:40:51
【问题描述】:
在 beta 测试期间,我们发现了连接池错误消息。因此,我一直在浏览代码并关闭未关闭的 SqlDataReader 对象。我需要知道的是如何关闭在 SqlDataSource 或 ObjectDataSource 标记的 SelectStatement 属性中指定的数据读取器(或者是否需要关闭)。不处理会不会有连接泄漏?
提前致谢!
【问题讨论】:
标签: asp.net ado.net connection-pooling
在 beta 测试期间,我们发现了连接池错误消息。因此,我一直在浏览代码并关闭未关闭的 SqlDataReader 对象。我需要知道的是如何关闭在 SqlDataSource 或 ObjectDataSource 标记的 SelectStatement 属性中指定的数据读取器(或者是否需要关闭)。不处理会不会有连接泄漏?
提前致谢!
【问题讨论】:
标签: asp.net ado.net connection-pooling
要提高 Close()/Dispose() 的性能,请考虑在释放或关闭读取器之前对关联的命令对象调用 Cancel(),尤其是当您没有到达记录集的末尾时。
例如:
using (var cmd = ... ))
{
using (var reader = (DbDataReader) cmd.ExecuteReader())
{
try
{
ConsumeData(reader); // may throw
}
catch(Exception)
{
cmd.Cancel();
throw;
}
}
}
【讨论】:
我的理解是,有了SqlDataSource,连接管理就替你做了,你什么都不怕。
ObjectDataSource 首先不直接与数据库对话,因此它是安全的——只要底层对象正确执行其连接和读取器管理。
正如其他人所提到的,Close() 和 using 是您与 ObjectDataSource 一起使用的课程的朋友。
我的预感是,如果您有效地清理了代码库,您可能已经根除问题。
【讨论】:
我们在生产环境中遇到了同样的问题。
解决了这个问题。首先的问题是,我的代码中根本没有 using 语句。 (它是几年前构建的,知识较少)。
然后我尝试将 SqlDataSource 放在 using 子句中。但这也无济于事。
这里的诀窍是,就像 tvanfosson 和 Mischa 建议的那样,将读者置于 using 子句中。这是实际关闭连接的对象。
在中等负载下,连接数减少到最小池大小 10。
【讨论】:
调用 .Dispose() 应该处理清理并释放任何持有的资源,但 .Close() method should be getting called as well when an object is done reading from the reader。
【讨论】:
我相信 SqlDataSource 会处理它自己的连接/阅读器问题,所以不用担心。至于您的手动连接,我发现这种模式在过去很有用:
using (SqlConnection connection = new SqlConnection(connectionString))
{
try
{
SqlCommand command = connection.CreateCommand();
command.CommandText = ...
connection.Open();
using (SqlDataReader reader = command.ExecuteReader())
{
do
{
while (reader.Read())
{
... handle each row ...
}
} while (reader.NextResult());
}
}
catch (Exception ex)
{
... error handling ...
}
finally
{
if (connection != null && connection.State == ConnectionState.Open)
{
connection.Close();
}
}
}
【讨论】:
我同意,对于 ObjectDataSource,关闭应由其 Select 方法处理。我的 ObjectDataSource Select 方法返回一个 SqlDataReader。我担心的是......将 SqlDataReader 返回到 UI 后关闭时是否会变得无用。例如请参阅以下示例代码。我没有尝试过,也不想在这个开发阶段这样做。
SqlDataReader MySelectMethod(){
SqlDataReader dr = null;
try{
dr = DBObject.GetDataReader();
return dr;
}
finally{
dr.Close();
}
}
感谢迄今为止收到的所有意见!
...........
我的理解是 SqlDataSource,连接管理 为您执行,并且您有 没什么好怕的。
ObjectDataSource 不与 数据库直接放在首位, 所以它是安全的——只要 底层对象执行其 连接和读卡器管理 正确。
正如其他人提到的,Close() 和 使用是你上课的朋友 您与 ObjectDataSource 一起使用
.
【讨论】: