我对在
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
或者释放这个对象占用的内存?
DataSet
和 DataTable
实际上没有任何非托管资源,因此 Dispose()
没有做太多事情。 Dispose()
和DataSet
中的DataTable
方法仅作为继承的副作用而存在——换句话说,它们实际上在终结中没有做任何有用的事情。
事实证明
DataSets
、DataViews
、DataTables
抑制了其构造函数中的终结;这就是为什么对它们显式调用 Dispose()
没有任何作用。
发生这种情况的原因可能是,如上所述,它们没有非托管资源;因此,尽管
MarshalByValueComponent
允许非托管资源,但这些特定的实现没有必要,因此可以放弃最终确定。
毫无疑问,应该对任何可终结的对象调用 Dispose。
数据表是可终结的。
调用Dispose可以显着加快内存回收速度。
在其MarshalByValueComponent
中调用GC.SuppressFinalize(this)
- 跳过此意味着在回收内存之前必须等待数十个(如果不是数百个)Dispose()
集合。Gen0
进一步阅读:
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()函数。它对我来说非常适合处理。