在DataTable上调用Dispose时,DataRow对象会发生什么?

时间:2015-06-22 00:49:53

标签: .net vb.net datatable datarow

这是.NET开始进入的地方。请考虑以下情况:

  1. 我有一个DataTable对象,其中包含许多DataRow个对象
  2. 我将一些DataRow个对象添加到数组
  3. 我在Dispose上致电DataTable
  4. 我有什么保证Dispose上的调用DataTable不会危及DataRow个对象(通过引用会影响添加到数组中的对象)?

    在这种情况下,

    MS documentation是零帮助。

    编辑:到目前为止,人们完全忽略了这一点。 IDisposable个对象意味着要尽快处理。我的代码将在一天中创建数千个DataTable个对象。如果他们实施IDispoable,我就不会离开那些未被处置的人。

    但是,我需要少数DataRow个对象来保持活着,因为这就是我的第三方二进制文件(我无法控制)所期望的。而且我需要它们来保持显着更长而不是DataTable个对象。

    我需要的只是描述Dispose DataTable实际上做什么的权威信息。看起来这些信息不存在,这就是我在这里寻求帮助的原因。有人可能会有一个参考,或者我忽略的文档,可以满足我的需求。

    编辑2:我已经测试了 Blam 建议,包括添加GC.Collect +奖励GC.WaitForPendingFinalizers +另外一个GC.Collect在处理DataTable之后。 DataRows似乎很好,仍然活着且可以访问。这是积极的,但唉不够权威包含在生产代码中: - (

2 个答案:

答案 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将编译您的代码以保持该网格,直到该数组不再引用该行。我看到的典型场景是,在创建网格和数组的父对象被处理之前,网格将在标记为删除的进程中保持不变,但从不进行垃圾回收,因为它有一个待处理的引用。

换句话说,避免这样做,因为通常它不会正确地垃圾收集网格直到应用程序关闭。

如果它是非托管代码,它应该在处置后首先引用它。