Pregunta

En Visual Studio, cuando escribo la línea "Implements IDisposable", el IDE agrega automáticamente:

  • a disposedValue variable miembro
  • a Sub Dispose() Implements IDisposable.Dispose
  • a Sub Dispose(ByVal disposing As Boolean)

El Dispose() debe dejarse en paz y el código de limpieza debe colocarse en Dispose(disposing).

Sin embargo, el Desechar Finalizar patrón dice que también deberías anular Sub Finalize() llamar Dispose(False).¿Por qué el IDE no agrega esto también?¿Debo agregarlo yo mismo o de alguna manera se llama implícitamente?

EDITAR: ¿Alguna idea de por qué el IDE agrega automáticamente el 80% de las cosas requeridas pero deja de lado el método Finalizar?¿No es el objetivo de este tipo de función ayudarte? no olvidar estas cosas?

EDITAR2: Gracias a todos por sus excelentes respuestas, ¡esto ahora tiene mucho sentido!

¿Fue útil?

Solución

Si realmente tiene recursos no administrados que el recolector de basura no limpiará automáticamente ni los limpiará en su Dispose(), entonces sí, debe hacer lo mismo en Finalize().

Si está implementando IDisposable por algún otro motivo, no es necesario implementar Finalize().

La pregunta básica es esta:Si no se llamara a Dispose() y se recolectara basura de su objeto, ¿se perdería memoria?En caso afirmativo, implemente Finalizar.Si no, no es necesario.Además, evite implementar Finalize "sólo porque es más seguro".Los objetos con finalizadores personalizados pueden necesitar potencialmente dos pases de GC para liberarlos: uno para colocarlos en la cola de finalizadores pendientes y un segundo pase para liberar realmente su memoria.

Otros consejos

No, no es necesario tener Finalizar a menos que tenga recursos no administrados para limpiar.

En la mayoría de los casos, la razón por la que una clase es desechable es porque mantiene referencias a otros objetos IDisposable administrados.En este caso, no es necesario ni deseable ningún método Finalize.

Implements IDisposable

Public Overloads Sub Dispose() Implements IDisposable.Dispose

    Dispose(True)
    GC.SuppressFinalize(Me)

End Sub

Protected Overloads Sub Dispose(ByVal disposing As Boolean)

    If disposing Then
        ' Free other state (managed objects).
    End If
    ' Free your own state (unmanaged objects).
    ' Set large fields to null.
End Sub

Protected Overrides Sub Finalize()

    Dispose(False)
    MyBase.Finalize()

End Sub

Como han dicho otros, no es necesario implementar un finalizador a menos que tenga directamente recursos no administrados.Además, suponiendo que esté trabajando en .NET 2.0 o posterior, es poco probable que alguna vez necesite implementar un finalizador porque normalmente SafeHandle se puede usar para empaquetar sus recursos no administrados.

escribí un publicación de blog bastante larga cubriendo los antecedentes y la implementación de IDisposable y finalizadores hace un tiempo, lo que puede valer la pena leer si no lo tiene totalmente claro.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top