【发布时间】:2010-10-20 20:45:49
【问题描述】:
最近我需要将 IDisposable 和对象终结的建议模式与 VS2005/VB.NET 提供的自动生成模式进行比较。我们已经使用了自动生成的一个,但在并排查看后,我对 VB.NET 实现有很多疑问......
作为参考,这里是 IDE 的实现:
Public Class Class1
Implements IDisposable
Private disposedValue As Boolean = False ''// To detect redundant calls
''// IDisposable
Protected Overridable Sub Dispose(ByVal disposing As Boolean)
If Not Me.disposedValue Then
If disposing Then
''// TODO: free managed resources when explicitly called
End If
''// TODO: free shared unmanaged resources
End If
Me.disposedValue = True
End Sub
#Region " IDisposable Support "
''// This code added by Visual Basic to correctly implement the disposable pattern.
Public Sub Dispose() Implements IDisposable.Dispose
''// Do not change this code. Put cleanup code in Dispose(ByVal disposing As Boolean) above.
Dispose(True)
GC.SuppressFinalize(Me)
End Sub
#End Region
End Class
问题:
- 如果在 GC 期间调用 Finalize() 而没有先显式调用 object.Dispose(),则 disposing:=false 并且“if disposing...”中的代码将永远不会执行以释放托管资源 - 从而导致它们保留在内存中,直到下一次 GC 通过。为什么不明确释放这些?这样做会不会在第一次 GC 传递时释放更多内存,并且在下一次传递之前不会将不需要的对象留在内存中?
- 为什么在 IDisposable 类上重写 Finalize() 时 IDE 不生成 Dispose(false) 调用?
- GC 如何知道调用 Dispose(false) 并确保它是 IDE 的实现,而不是以不同方式使用 bool 参数的自定义实现?
* ...如果 GC 测试它的存在并以假定某种实现的方式使用它(object.Dispose(disposing:=false)),Dispose(disposing as bool) 不应该是接口成员吗?
* 在
Dispose()和Dispose(disposing as boolean)都存在的情况下,为什么 GC 会选择调用重载的非接口成员?
总体而言,当显式调用 Dispose() 时执行扩展代码路径的假定附加值让我感到困惑(而不是无论是否显式调用 Dispose() 都会执行一个公共路径)。虽然我可以理解它是出于善意提供的,但如果不直接调用 Dispose(),除了延迟托管资源的实际释放之外,我看不到它如何做任何事情。从本质上讲,它似乎只能使对象图中的托管资源无法访问,将它们孤立起来直到第二次 GC 运行,而不是在已知不再需要它们的时候释放它们。
【问题讨论】:
标签: vb.net design-patterns visual-studio-2005 idisposable