我应该Dispose()DataSet和DataTable吗?

时间:2009-05-26 23:08:09

标签: datatable dataset dispose idisposable using

DataSet和DataTable都实现了IDisposable,因此,按照传统的最佳实践,我应该调用它们的Dispose()方法。

但是,从我到目前为止所读到的,DataSet和DataTable实际上并没有任何非托管资源,所以Dispose()实际上没有做太多。

另外,我不能只使用using(DataSet myDataSet...)因为DataSet有一组DataTables。

因此,为了安全起见,我需要遍历myDataSet.Tables,处理每个DataTables,然后处理DataSet。

那么,在我的所有DataSet和DataTables上调用Dispose()是否值得麻烦?

附录:

对于那些认为应该处理DataSet的人: 通常,处理的模式是使用usingtry..finally,因为您要保证将调用Dispose()。

然而,这对于一个集合来说真的很难实现。例如,如果对Dispose()的一个调用抛出异常,你会怎么做?你吞下它(这是“坏”),以便你可以继续处理下一个元素吗?

或者,你是否建议我只调用myDataSet.Dispose(),而忘记在myDataSet.Tables中处理DataTables?

13 个答案:

答案 0 :(得分:137)

以下是一些讨论,解释了为什么Dispose不是DataSet所必需的。

To Dispose or Not to Dispose ?

  

DataSet中的Dispose方法仅存在,因为继承的副作用 - 换句话说,它实际上并没有在最终化中做任何有用的事情。

Should Dispose be called on DataTable and DataSet objects?包含MVP的一些解释:

  

system.data命名空间(ADONET)不包含   非托管资源。因此,没有必要将这些中的任何一个处理掉   只要你没有给自己添加一些特别的东西。

Understanding the Dispose method and datasets?得到了当局Scott Allen的评论:

  

在实践中,我们很少处理DataSet,因为它提供的好处很少“

所以,有人认为目前没有理由在数据集上调用Dispose。

答案 1 :(得分:123)

答案 2 :(得分:22)

你应该假设它做了一些有用的事情,即使它在当前没有任何作用,也可以调用Dispose。 NET Framework的版本,不能保证它将在未来版本中保持这种状态,导致资源使用效率低下。

答案 3 :(得分:16)

即使对象没有非托管资源,处置也可能会破坏对象图,从而帮助GC。通常,如果object实现了IDisposable,则应调用Dispose()。

Dispose()实际上是否做某事取决于给定的类。在DataSet的情况下,Dispose()实现继承自MarshalByValueComponent。它从容器中删除自己并调用Disposed事件。源代码如下(用.NET Reflector反汇编):

protected virtual void Dispose(bool disposing)
{
    if (disposing)
    {
        lock (this)
        {
            if ((this.site != null) && (this.site.Container != null))
            {
                this.site.Container.Remove(this);
            }
            if (this.events != null)
            {
                EventHandler handler = (EventHandler) this.events[EventDisposed];
                if (handler != null)
                {
                    handler(this, EventArgs.Empty);
                }
            }
        }
    }
}

答案 4 :(得分:7)

您自己创建DataTables吗?因为通常不需要遍历任何Object的子节点(如在DataSet.Tables中),因为父节点的工作就是处理它的所有子节点成员。

通常,规则是:如果您创建了它并且它实现了IDisposable,请将其公开。如果你没有创建它,那么不要处置它,这是父对象的工作。但是每个对象可能都有特殊规则,请查看文档。

对于.net 3.5,它明确地说“不再使用时处理它”,这就是我要做的。

答案 5 :(得分:6)

每当对象实现IDisposeable时,我都会调用dispose。这是有原因的。

DataSet可能是巨大的记忆力。它们越早被标记为清理就越好。

<强>更新

我回答这个问题已经5年了。我仍然同意我的回答。如果存在dispose方法,则在完成对象时应调用它。 IDispose接口的实现是出于某种原因。

答案 6 :(得分:4)

如果您的意图或此问题的上下文实际上是垃圾收集,那么您可以将数据集和数据表明确设置为null或使用关键字using并让它们超出范围。尽管Tetraneutron早些时候说过,但处理并不多。 GC将收集不再引用的数据集对象以及超出范围的数据集对象。

我真的希望在强制要求回答之前强迫人们投票实际写评论。

答案 7 :(得分:1)

数据集实现IDisposable彻底的MarshalByValueComponent,它实现了IDisposable。由于管理数据集,因此调用dispose没有任何实际好处。

答案 8 :(得分:0)

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

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

答案 9 :(得分:0)

  

无需Dispose()     因为DataSet继承了MarshalByValueComponent类,并且MarshalByValueComponent实现了IDisposable接口

答案 10 :(得分:0)

这是正确处置DataTable的正确方法。

private DataTable CreateSchema_Table()
{
    DataTable td = null;
    try
    {
        td = new DataTable();
        //use table DataTable here
        
        return td.Copy();
    }
    catch {  }
    finally
    {
        if (td != null)
        {
            td.Constraints.Clear();
            td.Clear();
            td.Dispose();
            td = null;
        }
    }
}

答案 11 :(得分:0)

这可能是处置和释放DataSet消耗的内存的最佳/正确方法。

try
    {
        DataSet ds = new DataSet("DS");
        //use table DataTable here
        
    }
    catch {  }
    finally
    {
        if (ds != null)
                {
                    ds.EnforceConstraints = false;
                    ds.Relations.Clear();
                    int totalCount = ds.Tables.Count;

                    for (int i = totalCount - 1; i >= 0; i--)
                    {
                        DataTable td1 = ds.Tables[i];
                        if (td1 != null)
                        {
                            td1.Constraints.Clear();
                            td1.Clear();
                            td1.Dispose();
                            td1 = null;
                        }
                    }

                    ds.Tables.Clear();
                    ds.Dispose();
                    ds = null;
                }
    }

答案 12 :(得分:-1)

首先,我将检查Dispose对DataSet的作用。也许使用redgate的反射器会有所帮助。