我在阅读与使用子句一起使用时明确关闭和/或处理IDisposable对象的信息时,我已经阅读了相互矛盾的信息。
据我所知:
using (x) { .... }
编译时重写为:
try { .... } finally { if (x != null) x.Dispose(); }
这意味着在使用块结束时立即调用Dispose,对吗?
有些人建议即使在使用Using子句时也显式调用close和/或dispose,因为可能会有一些延迟等待Finally块执行?
其他人说在使用块中调用Dispose总是多余的。我倾向于同意,但我正在寻找明确的答案。
垃圾收集(GC)是否仅在未使用“使用”条款且您未明确关闭和处置时才会发挥作用?
以下面的方法为例(参见注释)。
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;
}
}
答案 0 :(得分:2)
你正确地描述了在块结束时调用的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方法中并且不需要调用它们,你必须阅读具体类的文档。
在您的情况下,我会将代码更改为
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;
}