2009-03-17 16 views
5

Hola sólo para clairfy si tengo el siguiente:y recolección de basura

using (Object1) { 
create Object2 
} 
// bookmark1 

Will Object2 ser destruida a lo largo de marca páginas 1 con Object1? Object2 es de StringReader y Object1 es de MemoryStream.

+0

Mientras estamos en ello - Will Object1 ser destruidos tan pronto como estamos en marca páginas 1 o solo ser no hace referencia a la espera de la GC a aparecer? – cwap

+0

Será "fuera de alcance" (que es lo mismo que sin referencia) y simplemente espere a que el GC aparezca y limpie en algún momento más tarde –

+0

[Vea una pregunta similar aquí.] (Http: // stackoverflow .com/questions/212198/what-is-the-c-using-block-and-why-should-i-use-it/212210 # 212210) – plinth

Respuesta

0

objeto2 no destruido (eliminado) con object1. Sin embargo, se crea un bloque de ámbito separado para la sentencia using por lo que object2 sale del alcance en este momento. Su eliminación no es determinista.

Además, si objeto2 es también un IDisposable usted puede hacer esto:

using (object1) 
using (object2) 
{ 
} // bookmark1 

No importa qué, se aplican las reglas normales de recolección de basura: los recursos gestionados (memoria) para el objeto todavía se manejan de manera normal . Usar/IDisposable solo libera recursos no administrados.

14

Ninguno de los objetos será destruido al final del bloque.

Objeto1 será Dispuesto, un concepto diferente; nada le sucederá a Object2.

Ambos objetos se recogerán y pueden finalizar en algún momento. La recolección de basura no es determinista; no puede confiar en cuándo ocurrirá.

Consulte IDisposable en MSDN para obtener más información.

2

A usando el bloque es el azúcar realmente sintáctica para una construcción como esta:

try 
{ 
    Brush b = new SolidBrush(Color.Red); 
} 
finally 
{ 
    b.Dispose(); 
} 

Así, 'b' será dispuesta en el extremo del bloque try menos que ocurra algo que está fuera del control de la aplicación .

+0

Cierre, pero no exactamente. En su código b aún está dentro del alcance, por lo que no se puede recopilar y no puede volver a utilizar el nombre aún cuando el bloque finalice. –

+0

Sí, lo acabo de arreglar. Gracias. –

1

Al final del bloque (marcador1), en su ejemplo, solo se eliminará el objeto 1. En el caso de una secuencia de archivos, esto significa que la secuencia se cerrará y se liberará el identificador, pero el objeto de cadena real seguirá estando en la memoria (listo para ser limpiado por el GC). En su caso, Object2 no se eliminará, por lo que el controlador que utiliza se mantendrá abierto. Eventualmente, el GC lo recogerá y llamará a su finalizador, momento en el que se publicará correctamente.

Si desea que ambos objetos se "limpien" correctamente, ambos deberán eliminarse, ya sea envolviéndolos en instrucciones de uso o llamando a Dispose manualmente.

Existe la alternativa, la sintaxis potencialmente más limpia, así:

 
using (Object1 obj1 = new Object1(), Object2 obj2 = new Object2()) 
{ 
    // Do something with obj1 & obj2 
} 

Si hace esto, obj1 Y obj2 ambos serán dispuestos en el extremo del bloque. En su caso, esto significa que ambos objetos se cerrarán y se liberarán sus identificadores. El GC los limpiará en una futura recolección de basura.

Para más detalles, véase MSDN's page on using.

Cuestiones relacionadas