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?
的范围时,是否会自动处理连接对象答案 0 :(得分:6)
你必须关心SqlConnection
的处置,因为它是一次性物品。你可以试试这个:
using(var sqlConnection = new SqlConnection(objUtilityDAL.ConnectionString))
{
using (SqlCommand cmd = con.CreateCommand())
{
// the rest of your code - just replace con with sqlConnection
}
}
我建议你用局部变量替换con
- 如果还没有(从你发布的代码中看不出来)。不需要为此目的使用类字段。只需创建一个局部变量,跟踪它就会更加清晰。
答案 1 :(得分:1)
您应该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;
}
至少多余(什么都不做但重新抛出异常),这就是为什么可以退出
答案 2 :(得分:1)
一般来说:
在.Net框架中,没有任何内容会自动处理。否则我们不需要IDisposable
接口。垃圾收集器只能处理托管资源,因此必须在dispose方法的代码中处理每个非托管资源。
因此,作为规则,实现IDisposable
的每个类的每个实例都必须通过调用它的Dispose
方法或隐式使用using
语句来显式处理。
作为最佳实践,您应该努力使用实现IDisposable
接口的任何内容作为使用语句中的局部变量:
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
}