为什么我必须使用Dispose()?

时间:2016-12-12 14:08:50

标签: c# ado.net dispose

这是我的代码:

public void InsertData()
{
    using (SqlConnection connection = new SqlConnection(DBHelper.ConnectionString))
    {
        using (SqlCommand command = new SqlCommand("Some Simple Insert Query", connection))
        {
            connection.Open();
            command.ExecuteNonQuery();
        }
    }
}

但是我找到了这个代码示例:

public void InsertData()
{
    SqlConnection connection = new SqlConnection(DBHelper.ConnectionString);
    connection.Open();
    SqlCommand command = new SqlCommand("Some Simple Insert Query", connection);
    command.ExecuteNonQuery();

    command.Dispose();
    connection.Close();
    connection.Dispose();
}

为什么作者使用

  

command.Dispose()

  

connection.Dispose();

在他们的代码中?

6 个答案:

答案 0 :(得分:5)

using只能用于 一次性的对象(即实现接口IDisposable的时候)。这样做会自动在该实例上调用Dispose。但是,与自己调用相反,using - 语句确保在发生该块时发生异常时也调用Dispose。所以使用这种方法更安全。

您的第一个示例与此相同:

try 
{
    SqlConnection connection = new SqlConnection(DBHelper.ConnectionString);
    connection.Open();
    SqlCommand command = new SqlCommand("Some Simple Insert Query", connection);
    try 
    {            
        command.ExecuteNonQuery();
    } 
    finally 
    {
        command.Dispose();
    }
}
finally
{
    connection.Dispose();
}

答案 1 :(得分:4)

异常被抛出时,您将资源泄露

'

异常的原因可能有所不同:

public void InsertData()
{
    SqlConnection connection = new SqlConnection(DBHelper.ConnectionString);
    connection.Open();
    SqlCommand command = new SqlCommand("Some Simple Insert Query", connection);
    command.ExecuteNonQuery(); // <- imagine that this throws exception 

    // and so these don't execute at all and you'll have two resources leaked: 
    //  1. Connection
    //  2. Command
    command.Dispose();
    connection.Close();
    connection.Dispose();
}

您可以使用 wordy 1. Insert failed (e.g. invalid field value insertion) 2. User doesn't have privelege required 3. RDMBS Internal error ... using模仿try

finally

答案 2 :(得分:3)

您不必在示例中使用dispose,因为using块会为您执行此操作。

见这里:using Statement (C# Reference)

答案 3 :(得分:3)

他正在使用connection.Dispose();因为这个人缺乏经验并且正在编写不安全的错误代码。如果抛出异常,连接将永远不会被处理掉,导致它保持打开状态,直到GC收集连接可能需要几分钟或几小时。

答案 4 :(得分:3)

在.Net IDisposable和Dispose方法中用于清理非托管资源。

.Net会跟踪托管资源,以便自动清理它们,但在处理非托管资源时需要提供一些帮助。

  

执行与释放,释放或重置非托管资源相关的应用程序定义任务。

https://msdn.microsoft.com/en-us/library/system.idisposable.dispose(v=vs.110).aspx

using语句是一种在您完成使用后自动调用Dispose方法的方法。

  

提供方便的语法,确保正确使用IDisposable对象。

如果调用异常,它甚至会被调用。

  

using语句确保即使在对象上调用方法时发生异常,也会调用Dispose。您可以通过将对象放在try块中然后在finally块中调用Dispose来实现相同的结果;实际上,这就是编译器如何翻译using语句。

https://msdn.microsoft.com/en-us/library/yh598w02.aspx

使用using语句的代码不正确。

它大部分时间都可以工作,但是如果发生异常,SqlConnection中的非托管资源可能会被清除。

  

通常,当您使用IDisposable对象时,您应该在using语句中声明并实例化它。

答案 5 :(得分:3)

using块只是try / finally Dispose()模式的语法糖。这些都在documentation中解释。

请注意,您还可以减少代码中的缩进:

using (SqlConnection connection = new SqlConnection(DBHelper.ConnectionString))
using (SqlCommand command = new SqlCommand("Some Simple Insert Query", connection))
{
    connection.Open();
    command.ExecuteNonQuery();
}
相关问题