我已阅读有关disposing of datasets的帖子,我仍然对析构函数有疑问。我知道帖子基本上说你不需要处理数据集,数据表和数据视图,但我的数据集是大量的,所以我想尽快释放那个内存。所以,我的问题是,我是否应该包含一个析构函数,即使在调用我的对象的dispose方法时将处理数据集?另外,再次向我解释为什么需要“bool处理”。
public DEditUtil(DataSet dsTxData)
{
this.dsTxData = dsTxData;
}
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
protected virtual void Dispose(bool disposing)
{
if (!disposed)
{
if (disposing)
dsTxData.Dispose();
disposed = true;
}
}
~DEditUtil()
{
Dispose(false);
}
答案 0 :(得分:4)
是的,一般情况下,只要满足以下任一条件,您就应该实施full IDisposable pattern:
IDisposable
的托管资源(这意味着他们反过来拥有非托管资源)终结器的存在(C ++ / C#称为“析构函数”的一般CLR术语)是处理由于某种原因未调用Dispose方法的情况。传递给受保护的Dispose()
方法的布尔值表示您是在公共Dispose
内还是在终结器内进行调用。
如果调用了公共Dispose
方法,则该调用堆栈是确定性的:您的dispose方法是直接调用的,因此您可以安全地调用子对象上的方法(包括Dispose
)。 / p>
如果您在终结器内,那么您不知道其他对象也在进行垃圾收集。通常,在终结器中调用托管对象上的方法可能不安全。
因此,布尔值基本上表示:“如果为true,则处置所有内容;如果为false,则仅处置我的非托管资源,并让其他人处理他们的内容。”
答案 1 :(得分:2)
一旦代码不再引用,DataSet
对象使用的内存将可用于垃圾回收。
垃圾收集器将在稍后(非确定)时间将该内存提供给程序。
这两件事都不依赖于是否有析构函数或调用Dispose
,所以答案是否定的 - 你不需要析构函数。
答案 2 :(得分:1)
不,你这里不需要任何其他方法调用,这已经足够你所做的了。
Dispose
将由运行时调用,您将释放资源,清理让我们决定如何以及何时执行此操作。
如果您有真的内存存在巨大问题,您可以尝试到cal GC.Collect()
来强制收集垃圾,这通常有效,但它永远不会以这种方式使用它的好习惯,所以尽量避免使用它。
编辑
根据评论,重要的是要注意你的案例中的执行流程,因为DataSet
清理只会 ,如果它不是{来自代码的{1}}和disposed==false
仅在代码的远程调用期间才会出现。
答案 3 :(得分:1)
用户编写的类很少使用终结器(或C#析构函数)用于除了记录调用Dispose
失败之外的任何目的。除非深入研究终结器如何工作的细节,并确切地保证它们运行的上下文有什么保证,否则不应该在终结器中调用任何其他对象的Dispose
方法。特别是,如果某个对象的Finalize()
方法正在运行,那么它拥有引用的任何IDisposable
对象通常都属于以下类别之一:
虽然在某些情况下某个对象可能需要在IDisposable
方法中清理另一个Finalize
对象,但在这种情况下正确使用Finalize
会很棘手,并且使用它不正确比根本不使用它更糟糕。除其他事项外,Finalize
通常仅在实体请求IDisposable
时运行,并且在放弃之前错误地无法调用Dispose
。通常最好将一个人的努力集中在确保Dispose
在放弃对象之前正确获取,而不是试图正确处理有缺陷的消费者代码。