C#SQL连接,命令和使用语句 - 显式关闭和处置或不处理?

时间:2016-03-03 06:49:41

标签: c# sql sql-server garbage-collection connection-timeout

我在阅读与使用子句一起使用时明确关闭和/或处理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;
    }
}

1 个答案:

答案 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;
}