这是.NET开始进入的地方。请考虑以下情况:
DataTable
对象,其中包含许多DataRow
个对象DataRow
个对象添加到数组Dispose
上致电DataTable
。我有什么保证Dispose
上的调用DataTable
不会危及DataRow
个对象(通过引用会影响添加到数组中的对象)?
MS documentation是零帮助。
编辑:到目前为止,人们完全忽略了这一点。 IDisposable
个对象意味着要尽快处理。我的代码将在一天中创建数千个DataTable
个对象。如果他们实施IDispoable
,我就不会离开那些未被处置的人。
但是,我需要少数DataRow
个对象来保持活着,因为这就是我的第三方二进制文件(我无法控制)所期望的。而且我需要它们来保持显着更长而不是DataTable
个对象。
我需要的只是描述Dispose
DataTable
实际上做什么的权威信息。看起来这些信息不存在,这就是我在这里寻求帮助的原因。有人可能会有一个参考,或者我忽略的文档,可以满足我的需求。
编辑2:我已经测试了 Blam 建议,包括添加GC.Collect
+奖励GC.WaitForPendingFinalizers
+另外一个GC.Collect
在处理DataTable
之后。 DataRows
似乎很好,仍然活着且可以访问。这是积极的,但唉不够权威包含在生产代码中: - (
答案 0 :(得分:3)
DataTable
没有重新实施MarshalByValueComponent.Dispose
,而且这种方法本身并没有多大帮助。因此,实际上,调用DataTable.Dispose
不会对表或其包含的数据执行任何操作。有趣的是,DataTable
甚至可以抑制构造函数中的最终化,因为it doesn't hold unmanaged resources。
现在,如果您查看DataRow
的定义,您会注意到它没有实现IDisposable
(或任何相关的事情),不会但它有一个依赖于表(它通过构造函数中传递的DataRowBuilder获得)。通常在这种情况下,你永远不想在拥有对象上调用dispose,直到绝对没有人再需要它为止,因为它可能导致已经处理掉那个父引用的副作用。
但是,在这种情况下,调用dispose实际上并没有做任何事情,这两种方式都没有关系。事实上,您将Dispose
称为过早优化,几乎没有效果,因此它是多余的。您的DataRow
及其包含的数据不会受到桌面呼叫处理的影响。
(对不起但不抱歉这个例子是C#而不是VB.NET,但在这个例子中两者没有区别,除了一个比另一个更丑; p)
var table = new DataTable();
table.RowDeleting += (sender, e) => {
Console.WriteLine("Deleting");
};
table.Clear();
table.Columns.Add("Foo");
table.Columns.Add("Bar");
var row = table.NewRow();
row["Foo"] = "Hello";
row["Bar"] = "World";
table.Rows.Add(row);
table.Dispose(); // "Dispose call! We've got a Dispose call here!"
row.Delete(); // "See? No one cares."
我不知道对于生产代码具有足够的权威性,但是你去了。
答案 1 :(得分:-2)
数据表永远不会被垃圾收集。 Dotnet将编译您的代码以保持该网格,直到该数组不再引用该行。我看到的典型场景是,在创建网格和数组的父对象被处理之前,网格将在标记为删除的进程中保持不变,但从不进行垃圾回收,因为它有一个待处理的引用。
换句话说,避免这样做,因为通常它不会正确地垃圾收集网格直到应用程序关闭。
如果它是非托管代码,它应该在处置后首先引用它。