vb.net - 为什么VS2005/VB.NET使用Dispose(处置为 bool 值)重载来实现IDisposable接口(interface)?

标签 vb.net design-patterns visual-studio-2005 idisposable

最近我需要将 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

问题:

  1. 如果在 GC 期间调用 Finalize(),而没有先显式调用 object.Dispose(),然后 dispose:=false,则“if dispose...”中的代码将永远不会执行以释放托管资源 - 从而导致它们保留在内存中直到下一次 GC 通过。为什么不明确释放这些?这样做不会在第一次 GC 传递时释放更多内存,并且不会在内存中留下不需要的对象直到下一次传递吗?
  2. 在 IDisposable 类上重写 Finalize() 时,为什么 IDE 不生成 Dispose(false) 调用?
  3. GC 如何知道调用 Dispose(false) 并确保它是 IDE 的实现,而不是以不同方式使用 bool 参数的自定义实现? * ...如果 GC 测试其存在并以假定某种实现(object.Dispose(disusing:=false))的方式使用它,那么 Dispose(disusing as bool) 不应该是接口(interface)成员吗? * 在双方都在场的情况下Dispose()Dispose(disposing as boolean)为什么 GC 会选择调用重载的非接口(interface)成员?

总的来说,我对拥有一个在 Dispose() 时执行的扩展代码路径的所谓附加值感到困惑。显式调用(与无论是否显式调用 Dispose() 都执行公共(public)路径相反)。虽然我可以理解它是出于良好的意图而提供的,但我看不出它除了延迟托管资源的实际释放之外还有什么作用,如果 Dispose()不直接调用。从本质上讲,它似乎只能使对象图中的托管资源无法访问,将它们孤立起来直到第二次 GC 运行,而不是在已知不再需要它们的时候释放它们。

最佳答案

您的问题存在逻辑错误...如果在终结器中调用 Dispose(),那么是的,disposeValue 将为 false,这意味着 如果不是 Me.disposeValue 那么... 将执行。为 dispose 传递的参数为 true,因此其中的所有代码都应该可以正常执行。

编辑 (结果 Finalizer 调用 Dispose(false))

表单上的终结器(仅当从未在表单上调用 Dispose() 时才运行)调用 Dispose(false)。其原因是 Form 当前正在被 GC 处理。因此,托管资源(即 Form 上的组件)将被收集,并且它们自己的终结器应在需要时调用 Dispose()。仅应在 Dispose(false) 中释放非托管资源。

关于vb.net - 为什么VS2005/VB.NET使用Dispose(处置为 bool 值)重载来实现IDisposable接口(interface)?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/773165/

相关文章:

.net - 单声道 - 在 'Sub Main' 中找不到 ''

vb.net - 使用嵌套命名空间而不是部分公共(public) NotInheritable 类是否有优势

c# - C# 中的 MyClass 等价物

deployment - 如何更改 Visual Studio 2005 部署项目的设置

.net - 在消息框/对话框上添加单选按钮

c++ - 使用享元模式在位图对象之间共享位图

java - 观察者设计模式方法在做两件事时是否违反SRP : setting and notifying

在调用堆栈为空的 Visual Studio 中调试小型转储

pointers - 结构副本问题

java - 您如何处理在运行时与依赖注入(inject)框架一起创建的对象?