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