C# 我是否需要显式地关闭和处理SQLConnection?
在上面的代码中,sqlconnection在托管代码中打开。因此,连接对象是否会在使用范围结束时自动处理?您必须注意C# 我是否需要显式地关闭和处理SQLConnection?,c#,asp.net,ado.net,sqlconnection,C#,Asp.net,Ado.net,Sqlconnection,在上面的代码中,sqlconnection在托管代码中打开。因此,连接对象是否会在使用范围结束时自动处理?您必须注意SqlConnection的处理,因为它是一次性对象。您可以尝试以下方法: SqlDataReader rdr = null; con = new SqlConnection(objUtilityDAL.ConnectionString); using (SqlCommand cmd = con.CreateCommand()) { try { if
SqlConnection
的处理,因为它是一次性对象。您可以尝试以下方法:
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;
}
}
我建议您用局部变量替换
con
——如果还没有(从您发布的代码中看不出)。没有必要为此使用类字段。只要创建一个局部变量,跟踪它就会更加清晰 您应该处理
手动创建的每个临时IDisposable
实例,即使用将它们包装到中:
using(var sqlConnection = new SqlConnection(objUtilityDAL.ConnectionString))
{
using (SqlCommand cmd = con.CreateCommand())
{
// the rest of your code - just replace con with sqlConnection
}
}
请注意
// 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()) {...}
}
}
}
至少是冗余的(它不做任何事情,只是重新抛出异常,同时丢失堆栈跟踪),这就是通常可以删除的原因:
在.Net framework中,不会自动处理任何内容。否则我们就不需要IDisposable
接口。垃圾收集器只能处理托管资源,因此必须在dispose方法的代码中处理每个非托管资源
因此,作为一项规则,实现IDisposable
的每个类的每个实例都必须通过调用其Dispose
方法显式地释放,或者通过using
语句隐式地释放
作为最佳实践,您应该努力将实现IDisposable
接口的任何东西作为using语句中的局部变量使用:
try {
...
}
catch (Exception ex) {
throw ex;
}
使用
语句的是语法上的糖。编译器将其转换为如下内容:
using(var whatever = new SomeIDisposableImplementation())
{
// use the whatever variable here
}
由于无论try
块中发生了什么,都保证运行finally
块,因此IDisposable
实例保证得到正确处理
具体来说,使用SqlConnection
时,您必须在完成后对其进行处理(dispose方法也将关闭连接,因此您不需要显式关闭它)-因此SqlConnection
的正确用法是始终作为using
语句中的局部变量:
var whatever = new SomeIDisposableImplementation();
try
{
// use the whatever variable here
}
finally
{
((IDisposable)whatever).Dispose();
}
您的连接对象不在using语句的范围内。它看起来像con
可能是一个字段。我不建议在using
语句中使用字段。因为一旦它在这个方法中被释放,并且你尝试在其他地方使用这个字段,你就会得到一个exeption,因为这个对象被释放了。使用局部变量不是更好地避免上述情况吗?此外,与局部变量相比,被处理的字段甚至没有任何优势。还是我错了?@L.guthatt通过快速阅读文章,我没有注意到这可能是一个类字段:)。说得好!正如我在更新中所写的那样,我认为利用类字段来达到这个目的不是一个好主意。谢谢。)非常高兴您更新了您的答案以添加此信息+非常感谢克里斯托斯。您建议我使用局部变量而不是类变量的观点是有道理的,因为它将在方法内部处理。我会改变逻辑。再次感谢!!非常感谢Dmitry BychenkoDo没有像它那样重新显示异常,否则您将丢失堆栈跟踪信息。。。只使用throw代码>非常感谢@Zohar peledgelad的帮助:-)
using(var con = new SqlConnection(connectionString))
{
// do stuff with con here
}