【问题标题】:Do I need to explicitly dispose SqlDataAdapter? [duplicate]我是否需要明确处置 SqlDataAdapter? [复制]
【发布时间】:2013-08-14 20:39:24
【问题描述】:

this thread 中,有一个建议是在操作之后,SqlDataAdapter 的实例像这样被显式地处理掉。

String connString = @"your connection string here";
String query = "select * from table";

SqlConnection conn = new SqlConnection(connString);        
SqlCommand cmd = new SqlCommand(query, conn);
conn.Open();
SqlDataAdapter da = new SqlDataAdapter(cmd);
da.Fill(dataTable);
conn.Close();
da.Dispose();

真的有必要吗? GC呢?

【问题讨论】:

    标签: c# database-connection


    【解决方案1】:

    强烈建议手动 Dispose IDisposable 对象。有一个很好的语法快捷方式:

    using SqlConnection con = new SqlConnection(connstring);
    using SqlCommand com = new SqlCommand();
    using SqlDataAdapter da = new SqlDataAdapter();
    com.Connection = con;
    //etc..
    

    这样,编译器将确保在所有使用 using 创建的对象超出范围后调用 Dispose()(它使用 try..finally 来实现这一点)。

    GC 不负责在你的对象上调用 Dispose(),它的主要职责是从堆中收集不再被引用的对象。一个例外是如果您的课程是可终结的。在这种情况下,GC 将确保首先调用对象的终结器,然后将其收集。您可以在 Finalizer 中调用 Dispose(),并且有一个很好的模式,称为“Dispose 方法”:http://msdn.microsoft.com/en-us/library/fs2xkftw.aspx

    但一般规则是(有几个例外):如果您正在实例化一个实现 IDisposable 的对象,则您有责任在其上调用 Dispose。

    【讨论】:

      【解决方案2】:

      来自 SqlDataAdapter Class 的 MSDN 文章中的代码示例:

      private static DataSet SelectRows(DataSet dataset, string connectionString,string queryString) 
      {
          using (SqlConnection connection = 
              new SqlConnection(connectionString))
          {
              SqlDataAdapter adapter = new SqlDataAdapter();
              adapter.SelectCommand = new SqlCommand(
                  queryString, connection);
              adapter.Fill(dataset);
              return dataset;
          }
      }
      

      SqlConnection 包含在 using 语句中,但不是 SqlDataAdapter

      所以我会说它不是必需的。

      也就是说,有些人倾向于如果它实现了 IDisposable,则将其丢弃

      在这种情况下,您还可以将 SqlDataAdapter 包装在 using statement 中。来自链接的文章:

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

      【讨论】:

        【解决方案3】:

        通常...是的,您会这样做。
        在某些情况下,不需要调用Dispose,但这些情况基于实现细节,不应被视为一般方法。

        Disposable 与垃圾收集无关。它是关于确定性资源清理的。 这些东西是平行宇宙。

        GC 可以收集对象,它实现了IDisposable,而无需调用Dispose。但是,如果该对象拥有操作系统句柄,例如,您有两种方法:立即释放句柄(调用 Dispose),或等待终结器(但终结器何时运行,只知道 GC)。

        当您的资源得到管理时,情况会更糟。
        托管资源不应在终结器中释放。因此,所有资源清理都是Dispose 方法的职责。如果不调用Dispose,托管资源将永远不会被清理(最流行的示例是事件取消订阅),这会导致内存泄漏。

        【讨论】:

          【解决方案4】:
          String connString = @"your connection string here";
          String query = "select * from table";
          
          SqlConnection conn = new SqlConnection(connString);        
          SqlCommand cmd = new SqlCommand(query, conn);
          conn.Open();
          **Using(SqlDataAdapter da = new SqlDataAdapter(cmd))
          {
              da.Fill(dataTable);
              conn.Close();
          }**
          

          一旦你到达区块的尽头,Using 就会为你处理掉它。

          【讨论】:

          • 并为连接添加一个using......这是这里最重要的资源。
          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2014-10-23
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2013-11-11
          • 2019-07-11
          • 2019-03-05
          相关资源
          最近更新 更多