在没有参考的情况下处置IDisposable

时间:2015-07-19 15:55:56

标签: c# .net vb.net garbage-collection idisposable

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

在这种情况下应该如何处理垃圾收集?

示例:

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

WebClient实施Dispose()

请随意根据需要重命名主题。

2 个答案:

答案 0 :(得分:2)

在这里,您应该重构代码以便进行处理。由于Using声明,这非常容易。

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

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

答案 1 :(得分:1)

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

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

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

如果在放弃之前使用Widget完成的最后一件事是调用Woozle,GC可能会注意到它获取myWidget的值,没有任何字段可以再次访问Widget,因此没有人会注意到它是否会消失。因为垃圾收集是一个异步过程,即使Woozle方法正在运行,也可能发生。如果Widget具有释放Finalize资源的析构函数或myWidget方法,则结果可能是灾难性的。

相比之下,如果Widget引用已被保留,以便在其上调用DisposeDispose执行GC.SuppressFinalizeGC.KeepAlive ,在完成对Woozle的调用之后,终结者才有可能继续运行。