C# SQL Connection、Command 和 Using 语句 - 是否显式关闭和处置?
C# SQL Connection, Command, and Using statements - explicitly close and dispose, or not?
我阅读了有关在与 Using 子句一起使用时显式关闭和/或处置 IDisposable 对象的相互矛盾的信息。
据我了解:
using (x) { .... }
编译后重写为:
try { .... } finally { if (x != null) x.Dispose(); }
这意味着在 using 块的末尾立即调用 Dispose,对吗?
有些人建议即使在使用 Using 子句时也显式调用关闭和/或处置,因为等待 Finally 块执行可能会有一些延迟?
还有人说在Using块中调用Dispose总是多余的。我倾向于同意,但我正在寻找一个明确的答案。
垃圾收集 (GC) 是否仅在未使用 Using 子句且您未明确关闭和处置时才起作用?
以下面的方法为例(见评论)。
public Musician GetMusician(int recordId)
{
Musician objMusician = null;
using(SqlConnection con = new SqlConnection(_connectionString))
{
con.Open();
using (SqlCommand cmd = new SqlCommand())
{
cmd.Connection = con;
cmd.CommandText = "selectMusician";
cmd.CommandType = CommandType.StoredProcedure;
cmd.Parameters.AddWithValue("@id", recordId);
using (SqlDataReader reader = cmd.ExecuteReader(CommandBehavior.CloseConnection))
{
if (reader.HasRows)
{
reader.Read();
objMusician = new Musician((int) reader["id"]);
objMusician.Name = (string) reader["name"];
}
if objMusician != null)
{
objMusician.Albums = Albums.GetAlbums((int)objMusician.ID);
objMusician.Tours = Tours.GetTours((int)objMusician.ID);
objMusician.Interviews = Interviews.GetInterviews((int)objMusician.ID);
}
// do these two lines close and dispose of the reader any faster?
reader.Close();
reader.Dispose();
}
// does this line dispose of the command any faster?
cmd.Dispose();
}
// do these two lines close and dispose of the connection any faster?
con.Close();
con.Dispose();
return objMusician;
}
}
您正确描述了在使用的块末尾调用的 Dispose 方法。
https://msdn.microsoft.com/en-us/library/yh598w02.aspx
GC 随机调用自定义对象的 Finalize() 方法(不是 直接调用 Dispose())。
https://msdn.microsoft.com/en-us/library/system.object.finalize.aspx
通常 Close 方法包含在 Dispose 方法中,不需要同时调用,具体请阅读文档 class。
根据你的情况,我会将代码更改为
public Musician GetMusician(int recordId)
{
Musician objMusician = null;
using(SqlConnection con = new SqlConnection(_connectionString))
{
con.Open();
using (SqlCommand cmd = new SqlCommand())
{
cmd.Connection = con;
cmd.CommandText = "selectMusician";
cmd.CommandType = CommandType.StoredProcedure;
cmd.Parameters.AddWithValue("@id", recordId);
using (SqlDataReader reader = cmd.ExecuteReader(CommandBehavior.CloseConnection))
{
if (reader.HasRows)
{
reader.Read();
objMusician = new Musician((int) reader["id"]);
objMusician.Name = (string) reader["name"];
}
if objMusician != null)
{
objMusician.Albums = Albums.GetAlbums((int)objMusician.ID);
objMusician.Tours = Tours.GetTours((int)objMusician.ID);
objMusician.Interviews = Interviews.GetInterviews((int)objMusician.ID);
}
}
}
}
return objMusician;
}
我阅读了有关在与 Using 子句一起使用时显式关闭和/或处置 IDisposable 对象的相互矛盾的信息。
据我了解:
using (x) { .... }
编译后重写为:
try { .... } finally { if (x != null) x.Dispose(); }
这意味着在 using 块的末尾立即调用 Dispose,对吗?
有些人建议即使在使用 Using 子句时也显式调用关闭和/或处置,因为等待 Finally 块执行可能会有一些延迟?
还有人说在Using块中调用Dispose总是多余的。我倾向于同意,但我正在寻找一个明确的答案。
垃圾收集 (GC) 是否仅在未使用 Using 子句且您未明确关闭和处置时才起作用?
以下面的方法为例(见评论)。
public Musician GetMusician(int recordId)
{
Musician objMusician = null;
using(SqlConnection con = new SqlConnection(_connectionString))
{
con.Open();
using (SqlCommand cmd = new SqlCommand())
{
cmd.Connection = con;
cmd.CommandText = "selectMusician";
cmd.CommandType = CommandType.StoredProcedure;
cmd.Parameters.AddWithValue("@id", recordId);
using (SqlDataReader reader = cmd.ExecuteReader(CommandBehavior.CloseConnection))
{
if (reader.HasRows)
{
reader.Read();
objMusician = new Musician((int) reader["id"]);
objMusician.Name = (string) reader["name"];
}
if objMusician != null)
{
objMusician.Albums = Albums.GetAlbums((int)objMusician.ID);
objMusician.Tours = Tours.GetTours((int)objMusician.ID);
objMusician.Interviews = Interviews.GetInterviews((int)objMusician.ID);
}
// do these two lines close and dispose of the reader any faster?
reader.Close();
reader.Dispose();
}
// does this line dispose of the command any faster?
cmd.Dispose();
}
// do these two lines close and dispose of the connection any faster?
con.Close();
con.Dispose();
return objMusician;
}
}
您正确描述了在使用的块末尾调用的 Dispose 方法。 https://msdn.microsoft.com/en-us/library/yh598w02.aspx
GC 随机调用自定义对象的 Finalize() 方法(不是 直接调用 Dispose())。 https://msdn.microsoft.com/en-us/library/system.object.finalize.aspx
通常 Close 方法包含在 Dispose 方法中,不需要同时调用,具体请阅读文档 class。
根据你的情况,我会将代码更改为
public Musician GetMusician(int recordId)
{
Musician objMusician = null;
using(SqlConnection con = new SqlConnection(_connectionString))
{
con.Open();
using (SqlCommand cmd = new SqlCommand())
{
cmd.Connection = con;
cmd.CommandText = "selectMusician";
cmd.CommandType = CommandType.StoredProcedure;
cmd.Parameters.AddWithValue("@id", recordId);
using (SqlDataReader reader = cmd.ExecuteReader(CommandBehavior.CloseConnection))
{
if (reader.HasRows)
{
reader.Read();
objMusician = new Musician((int) reader["id"]);
objMusician.Name = (string) reader["name"];
}
if objMusician != null)
{
objMusician.Albums = Albums.GetAlbums((int)objMusician.ID);
objMusician.Tours = Tours.GetTours((int)objMusician.ID);
objMusician.Interviews = Interviews.GetInterviews((int)objMusician.ID);
}
}
}
}
return objMusician;
}