DataTable.Dispose() 会将其从内存中删除吗?

问题描述 投票:0回答:3

我对在

Dispose()
上调用
DataTable
的效果感到困惑。这是我创建和处置表的代码:

DataTable dt = new DataTable();
SqlCommand cmd = new SqlCommand("sp_getData", SqlCon);
SqlCommand.CommandType = CommandType.StoredProcedure;
SqlCon.Open();
SqlDataReader dr = cmd.ExecuteReader();
dt.Load(dr);
SqlCon.Close();
grdView.DataSource = dt;

// Here I dispose the table as I no longer need it and want to free the memory.
dt.Dispose();

但是在处理完

DataTable
后我发现它仍然显示RowCount = 10k。

Dispose()
方法是否释放内存并将对象设置为
null
?我怎样才能让它
null
或者释放这个对象占用的内存?

c# winforms dispose system.data.datatable
3个回答
31
投票

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

事实证明

DataSets
DataViews
DataTables
抑制了其构造函数中的终结;这就是为什么对它们显式调用
Dispose()
没有任何作用。

发生这种情况的原因可能是,如上所述,它们没有非托管资源;因此,尽管

MarshalByValueComponent
允许非托管资源,但这些特定的实现没有必要,因此可以放弃最终确定。

这个巨大答案的概述

毫无疑问,应该对任何可终结的对象调用 Dispose。

数据表是可终结的。

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

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

进一步阅读:

请参阅此问题和相关的答案


9
投票

Dispose() 方法是否不释放内存并创建对象 空??

Dispose
并且处置模式不是用于回收托管内存或“删除”托管对象(这两件事是你不能做的,也是垃圾收集器的用途),它是用于处理非托管资源或其他托管资源的处置/释放具有可释放项目的资源,例如
SqlConnection
。它当然不会
null
参考,但可能会使其从处置转发时起无法使用。

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

如果您想使引用为空,只需使用

dt = null
即可,尽管这 不会 给您带来任何好处,因为
DataTable
实例由
grdView.DataSource
引用。
dt
grdView.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;

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

2
投票

© www.soinside.com 2019 - 2024. All rights reserved.