crear - idisposable implementation example c#
Finalizer e IDisposable (6)
No, tiene razón, si su objeto contiene un objeto que contiene un recurso no administrado, debe implementar IDisposable para que pueda llamar a Dispose en su Dispose, pero no necesita un finalizador ya que su finalizador se ocupará de ese asunto.
De hecho, tratar de hacer cualquier cosa con un miembro finalizable en un finalizador es precario, ya que el orden en que los finalizadores se ejecutarán no es determinista, por lo que puede obtener algunos errores desagradables si intenta hacer esto.
Como regla, es mucho mejor tener una clase que contenga 1 o 0 recursos no administrados. Y si tiene 1 recurso no administrado, debería tener tan poco otro estado como sea necesario para manejarlo (es decir, ningún otro miembro desechable). SafeHandle es una buena forma de lidiar con esto. Si una clase necesita tratar varios recursos no administrados, debe hacerlo mediante el manejo de dichos recursos a través de estas clases de controladores. Entonces, un finalizador y un IDisposable se vuelven fáciles; o bien tiene el único recurso no gestionado para tratar en ambos (suprime el finalizador si se llama a disponer) o solo necesita IDisposable.
Debido a que tener que tratar con recursos no administrados directamente es relativamente raro, lo más probable es que nunca tenga que escribir un finalizador (creo que lo he hecho una vez, en código real). Debido a que las personas sensatas no hacen mucho más en las clases que manejan recursos no administrados, el asunto Dispose (bool) es innecesario también.
Según la documentación (MSDN: enlace ), está claro que se debe utilizar el patrón IDisposable al implementar un finalizador.
¿Pero necesita implementar un finalizador si implementa IDisposable (para proporcionar una forma determinista de eliminar el objeto), y no tiene ningún recurso no administrado para limpiar?
Tal como lo veo, si la clase solo tiene recursos administrados y si no llama a Dispose, los recursos administrados serán limpiados automáticamente por el GC y, por lo tanto, no es necesario implementar el finalizador. ¿Me equivoco?
Además, ¿qué ocurre si uso mi método Dispose para limpiar los manejadores de eventos? Como Dispose no será llamado automáticamente por el GC, ¿debería implementar un Finalizer para asegurarme de que los manipuladores de eventos no estén conectados?
No debe agregar un finalizador a menos que tenga recursos no administrados.
Una clase que posee recursos desechables gestionados pero no recursos no administrados debe implementar el patrón Dispose
completo, pero no tener un finalizador.
Si la clase no está sealed
, debe llamar a GC.SuppressFinalize(this)
en su método Dispose()
en caso de que una clase heredada agregue un finalizador.
No, no necesita implementar un finalizador si tiene una clase que implementa IDisposable (es decir, si ha implementado el patrón correctamente y si solo tiene recursos gestionados para deshacerse de él).
(Si lo hace, puede afectar la vida útil de su objeto, ya que los objetos con finalizadores se agregan a la cola de finalización en el GC y pueden vivir más de lo necesario; esto puede ser un problema si los objetos son grandes).
Nunca tuve la necesidad de implementar un finalizador. Como saben, le da al objeto la oportunidad de hacer lo que sea necesario antes de GC. Todos los recursos deben ser liberados en el método de eliminación
Sí, si solo tienes recursos administrados, el GC los limpiará cuando se produzca la recolección de basura (y no haya referencias vivas que los señalen)
Pero en este caso, ¿por qué necesita implementar IDisposable en su tipo? Quiero decir, parece que considera que en su caso, no deshacerse de su objeto no es un gran problema, entonces ¿por qué alguien los descartaría?
También debe tener en cuenta que existe una penalidad de rendimiento con la recolección de elementos no utilizados durante el uso de Finalizer: cualquier objeto con un finalizador escapará al primer pase de GC, lo que degradará bastante la eficacia del GC si estos objetos son de corta duración.
Durante la primera recolección de basura durante la cual el objeto debe limpiarse, no lo hará para ejecutar el finalizador. El objeto se considerará como larga vida por el GC, incluso si ya debe ser limpiado.
Si solo tiene recursos administrados, entonces no necesita implementar IDisposable en absoluto. IDisposable está destinado a limpiar cosas que están más allá del dominio del GC, como identificadores nativos, conexiones de bases de datos, etc.
Si su control contiene controles que implementan IDisposable y deben liberar recursos nativos, entonces aún necesita implementar el patrón IDisposable y darles a sus controles la posibilidad de deshacerse.
El motivo para llamar a Dispose () en el finalizador es, como último recurso, si el objeto no se eliminó correctamente, el GC lo hará como último esfuerzo.