2009-03-17 14 views
5

Salve solo per clairfy se ho il seguente:Utilizzando e Garbage Collection

using (Object1) { 
create Object2 
} 
// bookmark1 

Will Object2 essere distrutta in bookmark1 insieme Object1? Object2 è di StringReader e Object1 è di MemoryStream.

+0

Mentre siamo in argomento - Will Object1 distrutti non appena ci siamo bookmark1 o sarà semplicemente essere non-referenziata, in attesa che il GC di presentarsi? – cwap

+0

Sarà "fuori ambito" (che è lo stesso di non referenziato) e quindi aspetta solo che il GC si visualizzi e lo pulisca prima o poi –

+0

[Vedi domanda simile qui.] (Http: // stackoverflow .com/questions/212198/what-is-the-c-using-block-and-why-should-i-use-it/212210 # 212210) – plinth

risposta

0

l'oggetto2 sarà non essere distrutto (eliminato) con oggetto1. Tuttavia, viene creato un blocco di ambito separato per l'istruzione using in modo che object2 passi fuori ambito a questo punto. È lo smaltimento non solo deterministico.

Inoltre, se oggetto2 è anche un IDisposable si può fare questo:

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

Non importa cosa, si applicano le normali regole di raccolta dei rifiuti: le risorse gestite (memoria) per l'oggetto sono ancora gestiti in modo normale . L'utilizzo di/IDisposable rilascia solo risorse non gestite.

14

Nessun oggetto sarà distrutto alla fine del blocco.

L'oggetto 1 sarà Smaltato, un concetto diverso; non succederà nulla a Object2.

Entrambi gli oggetti verranno raccolti e possono essere finalizzati, in seguito. La raccolta dei dati inutili non è deterministica: non è possibile fare affidamento su quando si verificherà.

Vedere IDisposable su MSDN per ulteriori informazioni.

2

A utilizzando blocco è zucchero davvero sintattico per un costrutto simile:

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

Quindi, 'b' sarà disposta all'estremità del blocco try meno accade qualcosa che è fuori del controllo dell'applicazione .

+0

Chiudi, ma non esattamente. Nel tuo codice b è ancora in ambito e quindi non può essere raccolto e non puoi riutilizzare il nome quando il blocco termina. –

+0

Sì, l'ho appena risolto. Grazie. –

1

Alla fine del blocco (segnalibro1), nell'esempio, verrà eliminato solo l'oggetto 1. Nel caso di un flusso di file, ciò significa che il flusso verrà chiuso e l'handle verrà rilasciato, ma l'oggetto stringa effettivo sarà ancora in memoria (pronto per essere pulito dal GC). Nel tuo caso, Object2 non verrà eliminato, quindi l'handle utilizzato verrà comunque mantenuto aperto. Alla fine, il GC lo raccoglierà e chiamerà il suo finalizzatore, nel qual caso verrà rilasciato correttamente.

Se si desidera che entrambi gli oggetti siano "ripuliti" correttamente, entrambi devono essere eliminati, sia mediante l'inserimento di istruzioni che mediante l'istruzione, oppure chiamando Dispose manualmente.

V'è l'alternativa, potenzialmente sintassi più pulito così:

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

Se si esegue questa operazione, obj1 e obj2 saranno entrambi essere smaltiti alla fine del blocco. Nel tuo caso, ciò significa che entrambi gli oggetti saranno chiusi e le loro maniglie rilasciate. Il GC provvederà a ripulirli in una futura raccolta dei rifiuti.

Per i dettagli, consultare MSDN's page on using.