有时,使用实现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.SuppressFinalize
或GC.KeepAlive
,那么在对Woozle
的调用完成之前,不可能运行终结器。