2012-03-12 10 views
8

Soy consciente de que todos los objetos que implementen IDisposable se deben eliminar tan pronto como ya no se necesiten para liberar la memoria utilizada por sus recursos no administrados.¿Debo molestarme en deshacerse de los objetos que comparten la vida útil del proceso?

Mi pregunta se refiere a los objetos que sé que de hecho vivirá hasta que el proceso de host se termina. ¿Haría alguna diferencia si los desecho o no? ¿Hay alguna posibilidad de que la memoria no se libere cuando el proceso muere? ¿Qué hay de los objetos GDI? ¿Serán liberados los identificadores de GDI cuando el proceso muera aunque no se eliminen?

Entiendo perfectamente que es una buena práctica deshacerse de todos los objetos de todos modos. Lo pregunto simplemente por curiosidad.

+0

http://blogs.msdn.com/b/kimhamil/archive/2008/11/05/when-to-call-dispose.aspx Guau, la gente saltó sobre mí como un paquete de perros en un gato de 3 patas por decir que no desechar. He descubierto que duele más de lo que ayuda. ¿No debería administrarse el ciclo de vida en un contenedor, no en un código difícil? – CrazyDart

+0

@CrazyDart Gracias, eso es una lectura iterativa, aunque trata principalmente con la pregunta "¿Debería eliminarse el objeto de tipo X normalmente?". La pregunta más específica que estoy tratando de responder es "¿Debería eliminarse el objeto de tipo X, que ** debe eliminarse ** normalmente", incluso si comparte la duración del proceso? – Rotem

+1

@CrazyDart ¿Cuándo se ha deshecho lastimarte? El enlace que le da le da algunos ejemplos de cuándo no se debe llamar a Dispose, pero la regla general debería ser llamarlo a menos que tenga una buena razón para no hacerlo. – hvd

Respuesta

7

Depende del objeto (recurso) en cuestión.

Cuando un proceso finaliza toda la memoria no administrada, se lanzarán filehandles y otros recursos del sistema operativo, incluso si los finalizadores asociados no se pudieron ejecutar.

Pero no estoy tan seguro de asas, db-mutex nombrados etc.

Así que antes de poder considerarlo seguro no llamar a Dispose, que tendría que saber sobre el tipo de recurso y cómo se se relaciona con el proceso. Es mucho más fácil llamar a Dispose() fuera del principio general.

Pero es un argumento teórico, la mayoría de las clases usarán SafeHandle : CriticalFinalizerObject. Entonces, no creo que sea un problema práctico real.

+0

De forma predeterminada, cada objeto que tenga un finalizador tendrá su finalizador ejecutándose. Es lo contrario que puede controlar desde su código: su 'Dispose' puede llamar a' GC.SuppressFinalize' para indicar que el finalizador ya no es necesario. (Edición: en realidad, creo que cada objeto tiene un finalizador, pero por defecto no hace nada). – hvd

+1

@hvd - en teoría, el GC podría omitir un finalizador normal. –

+0

@hvd - "Creo que cada objeto tiene un finalizador" correcto ", pero por defecto no hace nada". También es correcto y muy afortunado. Los finalizadores reales son caros. –

2

No. Por diseño, IDisposable está disponible para permitir que un programa libere un recurso no administrado antes, antes de lo que podría hacer el finalizador. Que se ejecuta en un momento bastante impredecible, generalmente más tarde cada vez que se realiza una recolección de basura. No puedes predecir cuándo sucede eso.

No tiene sentido deshacerse de la salida del programa, se garantiza que el finalizador se ejecutará justo antes de que se descargue AppDomain y se cierre el proceso.

Dicho esto, hay algunos abusos IDisposable, código que en realidad espera que lo llame. Pero eso normalmente se basa en el usando la instrucción, por lo que no es probable que te topes con eso.

+1

No se garantiza que los finalizadores se ejecuten en la salida del programa. Se garantiza que el sistema hará algún esfuerzo para ejecutarlos, pero eso no significa que realmente se ejecutarán. Los finalizadores son realmente asquerosos, y la mayoría de los objetos realmente no deberían tenerlos. – supercat

Cuestiones relacionadas