Datatable.Dispose()会从内存中删除吗?

时间:2013-09-18 09:53:33

标签: c# winforms dispose system.data.datatable

我通过非常简单的代码进行研究,并且一直看到数据表的dispose()结果

以下是代码

DataTable dt= new Datatable();
SqlCommand Cmd = new SqlCommand("sp_getData",SqlCon);
SqlCommand.CommandType= CommandType.StroedProcedure;
SqlCon.Open();
sqlDataReader dr=  cmd.ExecuteReader();
dt.Load(dr);
SqlCon.Close();
grdView.DataSource =dt;
dt.Dispose() // Here I dispose the table as it is no use for me & wanna memory free from this

但是在处理掉数据表之后我仍然发现它仍然显示RowCount = 10k。

Dispose()方法是不会释放内存和放大器。将对象设为null ??

如何将其设为null或释放此对象占用的内存?

3 个答案:

答案 0 :(得分:17)

DataSetDataTable实际上没有任何非托管资源,因此Dispose()实际上并没有做太多。 Dispose()DataSet中的DataTable方法仅因为继承的副作用而存在 - 换句话说,它实际上并没有在最终确定中做任何有用的事情。

事实证明,DataSetsDataViewsDataTables会抑制其构造函数中的最终化,这就是为什么在它们上面调用Dispose()明确无效的原因。

据推测,这是因为,如上所述,他们没有非托管资源;因此尽管MarshalByValueComponent允许非托管资源,但这些特定实现没有必要,因此可以放弃最终确定。

this Immense Answer概述:

  

毫无疑问,应该在任何Finalizable对象上调用Dispose。

     

DataTables是Finalizable。

     

调用Dispose可显着加快回收内存的速度。

     

MarshalByValueComponent在其GC.SuppressFinalize(this)中调用Dispose() - 跳过这意味着在回收内存之前必须等待数十个(如果不是数百个)Gen0个集合。

进一步阅读:

请参阅this question和相关的answer

答案 1 :(得分:7)

  

Dispose()方法是不会释放内存和放大器。使对象成为   null ??

Dispose并且处理模式不是用于回收托管内存或“删除”托管对象(您无法做到的事情以及垃圾收集器的用途),它用于处理非托管的处理/释放具有可释放项目的资源或其他受管资源,例如SqlConnection。它肯定不会null引用,但可能会使其在处置之前无法使用。

  

如何将其设为null或释放此占用的内存   对象??

如果您想使引用为空,只需dt = null即可,但不会给您带来任何好处,因为DataTable实例被grdView.DataSource引用}。 dtgrdView.DataSource都将引用同一个基础DataTable实例。

我还怀疑这是方法的一部分,其中dt无论如何都是方法范围。

你不应该过分担心这些事情。我更关心SqlConnection / try-finally之外的using,你有可能在那里打开连接。

我倾向于在实施Dispose的项目上调用IDisposable,我认为这是非常的理由:这是公共合同。调用它是否有效的事实是实施细节,并且可能会立即发生变化

<小时/> 顺便说一句,我会完全重写您的代码:

var dt = new Datatable();

using (var conn = new SqlConnection(""))
using (var comm = new SqlCommand("sp_getData", conn))
{
    conn.Open();

    using (var reader = comm.ExecuteReader())
    {
        dt.Load(reader);
    }
}

grdView.DataSource = dt;

答案 2 :(得分:2)

尝试使用Clear()函数。这对我来说非常适合处理。

DataTable dt = GetDataSchema();
//populate dt, do whatever...
dt.Clear();