2010-04-10 21 views
8

A continuación de my question here, si reemplazo una imagen en un cuadro de imagen, ¿debo deshacerme primero de la imagen original?Si reemplazo una imagen en un control PictureBox, ¿debo desechar primero la imagen original? .Net Winforms

O, ¿qué pasa con esta situación:

Dim bm As New Bitmap(32,32) 
bm = New Bitmap(32,32) 
bm = New Bitmap(32,32) 
bm = New Bitmap(32,32) 

¿El bm sólo necesitan estar dispuesto en el extremo, o debe ser eliminado antes de cada re-creación?


Gracias a todos por las respuestas. Un gran descuido de mi parte. Sabía que un control se ocupaba de deshacerse de sus hijos, pero no se me había ocurrido que debería deshacerme de una vieja imagen si la reemplazaba.

Respuesta

5

Sí, debe deshacerse del objeto viejo antes de crear una nueva imagen sobre la misma variable. Al crear una nueva imagen con la misma variable, está eliminando una referencia a ella. Si no hay referencias al objeto antiguo, significa que debe recogerlo el GC (Recolector de basura). Aunque técnicamente, esto "debería" eventualmente dar como resultado la liberación de la memoria suponiendo que el finalizador se asegure de que los recursos no administrados se solucionen, esta es una gran suposición (ni siquiera se puede suponer que se llamará al finalizador). , y causa más trabajo para el sistema. Los finalizadores no predeterminados causan trabajo adicional para el GC en términos de promoción del nivel de recolección de basura, lo que resulta en un mayor desglose de la memoria y la cantidad de veces que el GC debe ejecutarse para hacerlo.

Esto supone que todo está escrito para asegurarse de que el finalizador lo maneja. Cada vez que un objeto tiene un método Dispose (cualquier cosa que implementa IDisposable que BitMap), debe invocarse antes de eliminar la referencia al objeto (cayendo fuera del alcance, eliminando la referencia al objeto, etc.).

Aquí es un artículo sobre cómo el recolector de basura funciona en .net

http://www.devx.com/dotnet/Article/33167

aquí es cómo dice MS dispose/finalizador deben implementarse:

http://msdn.microsoft.com/en-us/library/b1yfkh5e.aspx

2

Sí se debería. Implementa IDisposable.
Como regla general, deseche todos los objetos que implemente IDisposable. No lo dejes a GC.

2

¿Necesita bm solo disponerse en el extremo, o debe desecharse antes de cada recreación?

Se debe eliminar antes de cada "recreación". No confundas un objeto con una referencia de objeto. "nuevo mapa de bits" crea un nuevo objeto. "bm" es una referencia que pasa a apuntar a ese objeto. Ellos no son los mismos. No está "recreando" ningún objeto aquí; está creando un nuevo objeto y, a continuación, descartando todas las referencias al objeto anterior, lo que significa que me recogerán basura algún tiempo en el futuro (próximo).

+0

Gracias por aclarar eso para mí. Soy consciente de todos los conceptos en su respuesta, pero algunos días tengo una congelación cerebral. ¿Olvidaste alguna vez cómo deletrear una palabra corta? Eso es lo que se siente. – Jules

2

Al cambiar la imagen asociada con un PictureBox, se debe llamar al Dispose en la imagen que estaba allí si y solo si nunca más va a usar esa imagen. Para saber eso, uno debería saber de dónde viene la vieja imagen. En algunos casos, la imagen se habrá creado solo con el fin de ser asignada al PictureBox. En otros casos, la imagen puede ser compartida y/o reutilizada.Si la imagen se creó con el único fin de asignarla al PictureBox, debería ser Dispose d si el PictureBox está dispuesto u otra imagen. Si se supone que la imagen se debe compartir o reutilizar, dichas condiciones no deben hacer que se elimine.

La forma correcta de resolver este tipo de problemas en general se tratara de clases que tienen IDisposable propiedades (como el PictureBox, con Image) para utilizar un método explícito SetImage en lugar de tener un mutable Image propiedad, y para el método SetImage para incluir una parámetro que indica si el PictureBox debe asumir la responsabilidad de desecharlo. Llamar a SetImage o Dispose en el PictureBox debe llamar al Dispose en la imagen retenida si y solo si la llamada anterior SetImage le dio esa responsabilidad. Desafortunadamente, PictureBox no funciona de esa manera, pero recomiendo utilizarlo como un patrón para las clases futuras que escriba que contienen objetos IDisposable.

+0

Esa es la única respuesta que se refiere a la primera parte de la pregunta, acerca de si desechar una imagen de 'PictureBox' antes de asignarla. –

+1

@UweKeim: pensé que era un tema importante que ninguna de las otras respuestas tocó. Me alegra que haya encontrado mi respuesta útil. Sospecho que se debe haber escrito el Framework antes de que la gente descubriera realmente cómo IDisposable iba a funcionar, y esas viejas clases son inamovibles, pero no hay razón para que las clases más nuevas repitan los viejos errores. – supercat

Cuestiones relacionadas