.net - net - implements idisposable dispose c#
¿Debo llamar a Dispose() en objetos gestionados? (12)
No puedo creer que todavía esté confundido acerca de esto pero, de cualquier manera, finalmente lo clavemos:
Tengo una clase que anula OnPaint para hacer algunos dibujos. Para acelerar las cosas, creo los bolígrafos, pinceles, etc. de antemano, en el constructor, para que OnPaint no tenga que seguir creando y desechándolos.
Ahora, me aseguro de disponer siempre de tales objetos, pero tengo la sensación de que no necesito hacerlo porque, a pesar de que implementan IDisposable, son objetos gestionados.
¿Es esto correcto?
Gracias por todas las respuestas, el problema sin duda ha sido clavado.
Me alegro de haber estado vigilante en el uso de ''usar'' para no tener que revisar todos mis códigos. Solo quería dejar en claro que no estaba siendo un usuario inútil.
Dejando de lado, tuve una situación extraña, recientemente, ¡en la que tuve que reemplazar un bloque de uso y llamar manualmente a disposición! Voy a desenterrar eso y crear una nueva pregunta.
¿Ha perfilado esto para ver si crear y desechar estos objetos realmente es un problema? No creo que lo sea.
Usted hace las cosas mucho más fáciles para usted y ciertamente menos propenso a errores simplemente siguiendo el patrón de crear en un bloque de uso.
Si desea crearlos una vez, entonces también implemente IDisposable en su clase propietaria y repita la eliminación sobre sus objetos de propiedad. No hay necesidad de un destructor (finalizador).
Casi no hay costo en hacer esto con los objetos que realmente no necesitan desechar, pero hay un gran costo si se olvida de Desechar en un objeto que sí lo necesita.
Aunque preguntaste sobre plumas y pinceles, Font es una clase con algunas peculiaridades extrañas. En particular, si uno crea una fuente con el fin de establecer la propiedad de la fuente de un control, uno es responsable de eliminar esa fuente (la propiedad no se transfiere al control), pero esa responsabilidad se puede llevar a cabo eliminando la fuente en en cualquier momento, incluso en cuanto se crea la fuente, antes de asignarla al control. Parece que la fuente es una combinación de un objeto de información administrada y un recurso GDI no administrado, y para algunos propósitos solo se necesita el primero. Diseño extraño - La fuente debería haber sido dos clases.
Escribí un componente de diagramación GDI + que usaba muchos lápices y pinceles. Los creé y los coloqué en el bloque de código que estaba haciendo el dibujo y el rendimiento nunca fue un problema. Mejor que luego tener un asa de larga duración colgando en el sistema operativo IMHO.
Hay una marcada ironía en tu enfoque. Al crear previamente las plumas / pinceles, está creando exactamente el problema que Dispose () está tratando de resolver. Esos objetos GDI estarán disponibles por más tiempo, tal como lo serían cuando no llames a Dispose (). En realidad es peor, estarán alrededor al menos hasta que se cierre el formulario.
Probablemente estén alrededor el tiempo suficiente para ser promovidos a la generación # 2. El recolector de basura no hace una colección gen # 2 muy a menudo, ahora es más importante llamar a Dispose () en ellos. Para ello, mueva el método Dispose () del formulario desde el archivo Designer.cs a su archivo form.cs y agregue las llamadas Dispose.
Pero, haz esto de la manera correcta. Las plumas y los pinceles son objetos muy baratos. Créalos cuando los necesite, en el evento Paint. Y use la declaración de uso para que sean eliminados de inmediato. Use la clase Cronómetro para volver a asegurarse de que esto realmente no causa ninguna desaceleración.
Necesitas disponer de ellos.
Los objetos gestionados gestionan su memoria por sí mismos. Pero la memoria no es el único recurso que utiliza un objeto. Dispose()
está destinado a liberar los otros recursos.
No, IDisposable es para objetos administrados que utilizan recursos no administrados. Como regla general, siempre debe disponer de ellos cuando haya terminado.
No, eso está mal. Estoy de acuerdo con Aaronaught.
Además, Microsoft recomienda, en una transmisión web a mediados de 2003 que presentó Don Box, que cada desarrollador de .Net debería deshacerse de sus propios objetos, ya sean administrados o no, ya que esto mejora el rendimiento del código en un 20%. Si se hace bien, puede ser una mejora sustancial del rendimiento. Así que es una habilidad fundamental que todo desarrollador de .net necesita saber y usar.
No, las Pen
y los Brush
no son objetos totalmente gestionados.
Contienen un identificador para un recurso no administrado, es decir, el objeto GDI correspondiente en el sistema de gráficos subyacente. (No estoy seguro de la terminología exacta aquí ...)
Si no los desecha, las asas no se soltarán hasta que el recolector de basura finalice los objetos, y no hay garantía de que esto suceda pronto, o no suceda.
Otros han aludido a los bloques de "uso" para objetos GDI; aquí hay un ejemplo de código:
using( var bm = new Bitmap() )
using( var brush = new Brush() )
{
// code that uses the GDI objects goes here
...
} // objects are automatically disposed here, even if there''s an exception
Tenga en cuenta que puede tener tantas líneas "usando" como desee para un solo bloque de código.
Creo que esta es una forma agradable y limpia de tratar con objetos desechables.
Realmente necesitas buscar la documentación para los pinceles, bolígrafos, etc.
Si no están usando recursos no administrados, es posible que no tenga que llamar a Dispose. Pero el patrón de uso / disposición es a veces "mal utilizado". Como ejemplo, considere el marco MVC de ASP.NET. Aquí puedes escribir algo como:
using(Html.BeginForm(...)){
///HTML input fields etc.
}
Cuando se Html.BeginForm(...)
, se generará una etiqueta FORM
. Cuando finalice la declaración de uso, se llamará a Dispose
en el objeto devuelto desde Html.BeginForm(...)
. Llamar a Dispose
hace que la etiqueta final de FORM
se reproduzca. De esta manera, el compilador aplicará el emparejamiento de las etiquetas FORM, por lo que no olvidará la etiqueta de cierre.
Vea mi respuesta aquí en un hilo similar. debe abordar su pregunta y explicar las ramificaciones si no llama a Dispose.
No es correcto Necesitas disponer los objetos que implementan IDisposable
. Es por eso que implementan IDisposable
, para especificar el hecho de que envuelven (directa o indirectamente) los recursos no administrados.
En este caso, el recurso no administrado es un identificador de GDI, y si no los dispone cuando realmente haya terminado con ellos, perderá esos manejadores. Ahora, estos objetos en particular tienen finalizadores que harán que se liberen los recursos cuando se active el GC, pero no hay forma de saber cuándo ocurrirá eso. Puede ser dentro de 10 segundos, puede ser dentro de 10 días; Si su aplicación no genera suficiente presión de memoria para hacer que el GC inicie y ejecute los finalizadores en esos pinceles / plumas / fuentes / etc., puede terminar muriendo de hambre el sistema operativo de GDI antes de que el GC se dé cuenta de lo que está pasando.
Además, no tiene garantía de que cada contenedor no administrado realmente implemente un finalizador. El .NET Framework en sí mismo es bastante consistente en el sentido de que las clases que implementan IDisposable
implementan con el patrón correcto , pero es completamente posible que alguna otra clase tenga una implementación dañada que no incluya un finalizador y, por lo tanto, no se limpie correctamente a menos que Dispose
se llama explícitamente en él. En general, el propósito de IDisposable
es que no debe saber o preocuparse por los detalles específicos de la implementación; más bien, si es desechable, entonces dispones de él, punto.
Moraleja de la historia: Siempre disponga de objetos IDisposable
. Si su clase "posee" objetos IDisposable
, entonces debería implementarse IDisposable
.