在没有参考的情况下处理一次性物品

本文关键字:处理 一次性 情况下 参考 | 更新日期: 2023-09-27 18:03:30

有时,使用实现Dispose()的类的实例时,实际上不保留对该实例的任何引用。

对于这种情况下的垃圾收集应该做些什么?

的例子:

MsgBox(New System.Net.WebClient().DownloadString("http://www.website.com"))

WebClient实现Dispose()

请随意重命名您认为合适的主题

在没有参考的情况下处理一次性物品

在这里,您应该重构代码以便进行处理。多亏了Using语句,这非常容易。

我现在知道为什么WebClient需要被处理。据我所知,在简单的用例中,它不会占用任何资源。

这个问题与GC无关。当GC发现该对象未被引用时,该对象将像其他对象一样被清理。

只有在非常罕见的情况下,正确编写的代码才允许在没有首先调用Dispose的情况下放弃对资源持有对象的所有引用。除了延迟清理造成的问题之外,粗心地处理IDisposable对象在某些情况下也会导致过早地清理。

例如,假设有一个类Widget,它使用Widget的某种本地句柄,并且它有一个方法

void Woozle()
{
  NativeWidget.Woozle(myWidget));
}

如果在放弃之前对Widget做的最后一件事是调用Woozle, GC可能会注意到它获取了myWidget的值,Widget的所有字段都不能再被访问,因此没有人会注意到它是否消失了。由于垃圾收集是一个异步过程,因此即使在Woozle方法运行时也可能发生。如果Widget有析构函数或Finalize方法释放myWidget资源,结果可能是灾难性的。

相反,如果为了调用Dispose而保留了Widget引用,并且Dispose调用了GC.SuppressFinalizeGC.KeepAlive,那么在对Woozle的调用完成之前,不可能运行终结器。