我是否需要明确关闭和处理 SQLConnection?
Do I need to close and dispose the SQLConnection explicitly?
SqlDataReader rdr = null;
con = new SqlConnection(objUtilityDAL.ConnectionString);
using (SqlCommand cmd = con.CreateCommand())
{
try
{
if (con.State != ConnectionState.Open)
con.Open();
cmd.CommandType = CommandType.StoredProcedure;
cmd.Parameters.Add(Parameter);
cmd.CommandText = _query;
rdr = cmd.ExecuteReader();
}
catch (Exception ex)
{
throw ex;
}
}
在上面的代码中,sqlconnection 在托管代码中打开。因此,连接对象是否会在结束 USING 范围时自动释放?
您必须关心 SqlConnection
的处置,因为它是一次性物品。你可以试试这个:
using(var sqlConnection = new SqlConnection(objUtilityDAL.ConnectionString))
{
using (SqlCommand cmd = con.CreateCommand())
{
// the rest of your code - just replace con with sqlConnection
}
}
我建议您用局部变量替换 con
- 如果还没有(从您发布的代码中看不出来)。无需为此目的使用 class 字段。只需创建一个局部变量,跟踪它就会清楚得多。
您应该 Dispose
每个 临时 IDisposable
您创建 手动 的实例,即将它们包装到 using
:
// Connecton is IDisposable; we create it
// 1. manually - new ...
// 2. for temporary usage (just for the query)
using (SqlConnection con = new SqlConnection(objUtilityDAL.ConnectionString)) {
// Check is redundant here: new instance will be closed
con.Open();
// Command is IDisposable
using (SqlCommand cmd = con.CreateCommand()) {
cmd.CommandType = CommandType.StoredProcedure;
cmd.Parameters.Add(Parameter);
cmd.CommandText = _query;
// Finally, Reader - yes - is IDisposable
using (SqlDataReader rdr = cmd.ExecuteReader()) {
// while (rdr.Read()) {...}
}
}
}
请注意
try {
...
}
catch (Exception ex) {
throw ex;
}
至少 冗余 (它 什么都不做 但重新抛出异常,同时丢失堆栈跟踪)这就是为什么可以被删除的原因
总的来说:
在 .Net 框架中,不会自动处理任何内容。否则我们将不需要 IDisposable
接口。垃圾收集器只能处理托管资源,因此每个非托管资源都必须在 dispose 方法的代码中处理。
因此,作为一项规则,实现 IDisposable
的每个 class 的每个实例都必须通过调用它的 Dispose
方法显式处理或使用 [=16= 隐式处理]声明。
作为最佳实践,您应该努力使用任何实现 IDisposable
接口的东西作为 using 语句中的局部变量:
using(var whatever = new SomeIDisposableImplementation())
{
// use the whatever variable here
}
using
语句是语法糖。编译器将它翻译成这样:
var whatever = new SomeIDisposableImplementation();
try
{
// use the whatever variable here
}
finally
{
((IDisposable)whatever).Dispose();
}
由于 finally
块保证 运行 无论 try
块中发生什么,你的 IDisposable
实例保证被正确处理。
特别是 SqlConnection
,in order to return the connection object back to the connection pool,你必须在完成后处理它(Dispose 方法也会关闭连接,所以你不需要显式关闭它) - 所以正确SqlConnection
的使用总是 作为 using
语句中的局部变量:
using(var con = new SqlConnection(connectionString))
{
// do stuff with con here
}
SqlDataReader rdr = null;
con = new SqlConnection(objUtilityDAL.ConnectionString);
using (SqlCommand cmd = con.CreateCommand())
{
try
{
if (con.State != ConnectionState.Open)
con.Open();
cmd.CommandType = CommandType.StoredProcedure;
cmd.Parameters.Add(Parameter);
cmd.CommandText = _query;
rdr = cmd.ExecuteReader();
}
catch (Exception ex)
{
throw ex;
}
}
在上面的代码中,sqlconnection 在托管代码中打开。因此,连接对象是否会在结束 USING 范围时自动释放?
您必须关心 SqlConnection
的处置,因为它是一次性物品。你可以试试这个:
using(var sqlConnection = new SqlConnection(objUtilityDAL.ConnectionString))
{
using (SqlCommand cmd = con.CreateCommand())
{
// the rest of your code - just replace con with sqlConnection
}
}
我建议您用局部变量替换 con
- 如果还没有(从您发布的代码中看不出来)。无需为此目的使用 class 字段。只需创建一个局部变量,跟踪它就会清楚得多。
您应该 Dispose
每个 临时 IDisposable
您创建 手动 的实例,即将它们包装到 using
:
// Connecton is IDisposable; we create it
// 1. manually - new ...
// 2. for temporary usage (just for the query)
using (SqlConnection con = new SqlConnection(objUtilityDAL.ConnectionString)) {
// Check is redundant here: new instance will be closed
con.Open();
// Command is IDisposable
using (SqlCommand cmd = con.CreateCommand()) {
cmd.CommandType = CommandType.StoredProcedure;
cmd.Parameters.Add(Parameter);
cmd.CommandText = _query;
// Finally, Reader - yes - is IDisposable
using (SqlDataReader rdr = cmd.ExecuteReader()) {
// while (rdr.Read()) {...}
}
}
}
请注意
try {
...
}
catch (Exception ex) {
throw ex;
}
至少 冗余 (它 什么都不做 但重新抛出异常,同时丢失堆栈跟踪)这就是为什么可以被删除的原因
总的来说:
在 .Net 框架中,不会自动处理任何内容。否则我们将不需要 IDisposable
接口。垃圾收集器只能处理托管资源,因此每个非托管资源都必须在 dispose 方法的代码中处理。
因此,作为一项规则,实现 IDisposable
的每个 class 的每个实例都必须通过调用它的 Dispose
方法显式处理或使用 [=16= 隐式处理]声明。
作为最佳实践,您应该努力使用任何实现 IDisposable
接口的东西作为 using 语句中的局部变量:
using(var whatever = new SomeIDisposableImplementation())
{
// use the whatever variable here
}
using
语句是语法糖。编译器将它翻译成这样:
var whatever = new SomeIDisposableImplementation();
try
{
// use the whatever variable here
}
finally
{
((IDisposable)whatever).Dispose();
}
由于 finally
块保证 运行 无论 try
块中发生什么,你的 IDisposable
实例保证被正确处理。
特别是 SqlConnection
,in order to return the connection object back to the connection pool,你必须在完成后处理它(Dispose 方法也会关闭连接,所以你不需要显式关闭它) - 所以正确SqlConnection
的使用总是 作为 using
语句中的局部变量:
using(var con = new SqlConnection(connectionString))
{
// do stuff with con here
}