在没有引用的情况下处理 IDisposable
Disposing of IDisposable Without Reference
有时会使用实现 Dispose()
的 class 的实例,但实际上并未保留对该实例的任何引用。
这种情况下垃圾回收应该怎么办?
示例:
MsgBox(New System.Net.WebClient().DownloadString("http://www.website.com"))
WebClient
实施 Dispose()
.
请随意重命名主题。
在这里,您应该重构代码以便进行处置。由于 Using
声明,这非常容易。
我现在知道为什么 WebClient
需要处理了。据我所知,在简单的用例中,它不会占用任何资源。
此问题与GC无关。当 GC 发现它未被引用时,该对象将像任何其他对象一样被清理。
只有在极少数情况下,正确编写的代码才能允许放弃对资源持有对象的所有引用,而无需首先调用它 Dispose
。除了延迟清理导致的问题之外,IDisposable
对象的粗心处理在某些情况下也会导致 提前 清理。
例如,假设一个 class Widget
使用某种本机句柄 Widget
,并且它有一个方法
void Woozle()
{
NativeWidget.Woozle(myWidget));
}
如果在放弃之前用 Widget
完成的最后一件事是调用 Woozle
,GC 可能会注意到它获取了 myWidget
、[=42 的值=] 的字段 Widget
可以再次访问,因此如果它消失,没有人会注意到。因为垃圾收集是一个异步过程,所以即使 Woozle
方法是 运行,也可能会发生这种情况 。如果 Widget
有释放 myWidget
资源的析构函数或 Finalize
方法,结果可能是灾难性的。
相比之下,如果 Widget
引用是为了在其上调用 Dispose
而保留的,并且 Dispose
执行 GC.SuppressFinalize
或 GC.KeepAlive
,那么在对 Woozle
的调用完成之前,终结器 运行 是不可能的。
有时会使用实现 Dispose()
的 class 的实例,但实际上并未保留对该实例的任何引用。
这种情况下垃圾回收应该怎么办?
示例:
MsgBox(New System.Net.WebClient().DownloadString("http://www.website.com"))
WebClient
实施 Dispose()
.
请随意重命名主题。
在这里,您应该重构代码以便进行处置。由于 Using
声明,这非常容易。
我现在知道为什么 WebClient
需要处理了。据我所知,在简单的用例中,它不会占用任何资源。
此问题与GC无关。当 GC 发现它未被引用时,该对象将像任何其他对象一样被清理。
只有在极少数情况下,正确编写的代码才能允许放弃对资源持有对象的所有引用,而无需首先调用它 Dispose
。除了延迟清理导致的问题之外,IDisposable
对象的粗心处理在某些情况下也会导致 提前 清理。
例如,假设一个 class Widget
使用某种本机句柄 Widget
,并且它有一个方法
void Woozle()
{
NativeWidget.Woozle(myWidget));
}
如果在放弃之前用 Widget
完成的最后一件事是调用 Woozle
,GC 可能会注意到它获取了 myWidget
、[=42 的值=] 的字段 Widget
可以再次访问,因此如果它消失,没有人会注意到。因为垃圾收集是一个异步过程,所以即使 Woozle
方法是 运行,也可能会发生这种情况 。如果 Widget
有释放 myWidget
资源的析构函数或 Finalize
方法,结果可能是灾难性的。
相比之下,如果 Widget
引用是为了在其上调用 Dispose
而保留的,并且 Dispose
执行 GC.SuppressFinalize
或 GC.KeepAlive
,那么在对 Woozle
的调用完成之前,终结器 运行 是不可能的。