垃圾收集,我们应该依赖它吗?

时间:2010-08-23 09:01:35

标签: c# garbage-collection

在代码中,我们说:

using (SqlConnection cn = new SqlConnection(ConfigurationManager.ConnectionStrings["LocalSqlServer"].ToString()))
{
    cn.Open();

    // Set all previous settings to inactive
    using (SqlCommand cmd = new SqlCommand("UPDATE tblSiteSettings SET isActive = 0", cn))
    {                            
        cmd.ExecuteNonQuery();
    }

    cn.Close();
}

cn.close在技术上并不需要,因为垃圾收集会为我们处理连接。

然而,无论如何,我总是喜欢关闭它,而不是依靠垃圾收集。这不好吗?浪费时间?或者认为不依赖自动化的良好做法?

提前感谢您的想法和意见。我将此标记为社区维基,因为它可能是主观的。

2 个答案:

答案 0 :(得分:15)

你永远不应该依赖GC。 Raymond Chen的blog article about this是一个很好的起点。基本上,如果您没有手动Close / Dispose您的连接,那么无法保证它会发生,因为否则它只会在从Dispose调用时发生Finalizer可能永远不会发生:

  

正确编写的程序不能   假设终结者将会运行   在节目之前的任何时候   终止。

是的,在实践中,您的连接的终结器可能最终会发生,但即使这样,您仍然保持实时连接的时间超过实际需要的时间。如果数据库在任何时候只允许有限数量的实时连接,则会产生问题。

您正在做的事情被视为良好做法:当您完成资源后,将其释放。如果对象是IDisposableDispose,则可以。

答案 1 :(得分:6)

首先 - 在您的示例中,您使用的是IDisposable接口,它与GC完全无关。实质上,您的代码编译为:

SqlConnection cn = null;
try
{
    cn = new SqlConnection(ConfigurationManager.ConnectionStrings["LocalSqlServer"].ToString());
    cn.Open();

    // Set all previous settings to inactive
    using (SqlCommand cmd = new SqlCommand("UPDATE tblSiteSettings SET isActive = 0", cn))
    {
        cmd.ExecuteNonQuery();
    }
    cn.Close();
}
finally
{
    if ( cn != null )
        cn.Dispose();
}

由于cn.Dispose()cn.Close()在这种情况下是相同的 - 是的,后者是多余的。

现在,如果你想谈论GC,那么你会这样写:

    SqlCOnnection cn = new SqlConnection(ConfigurationManager.ConnectionStrings["LocalSqlServer"].ToString());
    cn.Open();

    // Set all previous settings to inactive
    using (SqlCommand cmd = new SqlCommand("UPDATE tblSiteSettings SET isActive = 0", cn))
    {
        cmd.ExecuteNonQuery();
    }
    cn = null; // Or just leave scope without doing anything else with cn.

在这种情况下,GC将关闭打开的连接并将其返回池中。在这种情况下,这意味着你无法预测何时发生。在实践中,这个代码(很有可能)会泄漏SqlConnections,很快你就会用完它们(你会得到一个TimeoutException,因为池中没有可用的连接)。

所以,是的,你上面的例子是正确的方法。每当您使用一些实现IDisposable的对象时,将其包装在using块中。而且你不需要打扰.Close(),尽管它也没有伤害。我个人不写它。更少的代码,更少的混乱。