2009-03-17 8 views
5

Salut juste clairfy si je donne les résultats suivants:L'utilisation et la collecte des ordures

using (Object1) { 
create Object2 
} 
// bookmark1 

Will Object2 être détruit à bookmark1 avec Object1? Object2 est de StringReader et Object1 est de MemoryStream.

+0

Pendant que nous y sommes - Est-ce Object1 être détruits dès que nous sommes à bookmark1 ou sera juste être non-référencés et en attendant le GC de se présenter? – cwap

+0

Il sera "hors de portée" (ce qui est le même que non référencé) et donc attendre que le GC apparaisse et le nettoie plus tard –

+0

[Voir la question similaire ici.] (Http: // stackoverflow .com/questions/212198/what-is-the-c-using-block-et-pourquoi-devrais-je-l'utiliser/212210 # 212210) – plinth

Répondre

0

objet2 sera pas être détruit (disposé) avec object1. Cependant, un bloc de portée distinct est créé pour l'instruction using, de sorte que object2 sort de sa portée à ce stade. Sa disposition n'est tout simplement pas déterministe.

En outre, si object2 est aussi un IDisposable que vous pouvez faire ceci:

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

Peu importe, les règles de collecte des ordures ménagères sont applicables: les ressources gérées (mémoire) pour l'objet sont encore gérées de façon normale . L'utilisation de/IDisposable ne libère que des ressources non gérées.

14

Aucun objet ne sera détruit à la fin du bloc.

L'objet 1 sera Disposé, un concept différent; rien n'arrivera à Object2.

Les deux objets seront collectés et pourront être finalisés ultérieurement. La collecte des ordures est non-déterministe - vous ne pouvez pas compter sur quand cela se produira.

Voir IDisposable sur MSDN pour plus d'informations.

2

A l'aide de bloc est vraiment sucre syntaxique pour une construction comme celle-ci:

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

Ainsi, « b » sera disposé à l'extrémité du bloc d'essai à moins que quelque chose se passe qui est en dehors du contrôle de l'application .

+0

Fermer, mais pas exactement. Dans votre code b est toujours dans la portée, et donc il ne peut pas être collecté et vous ne pouvez pas réutiliser le nom encore quand le bloc se termine. –

+0

Oui, je viens de le réparer. Merci. –

1

A la fin du bloc (signet1), dans votre exemple, seul l'objet 1 sera éliminé. Dans le cas d'un flux de fichier, cela signifie que le flux sera fermé et que le descripteur sera libéré, mais l'objet chaîne actuel sera toujours en mémoire (prêt à être nettoyé par le GC). Dans votre cas, Object2 ne sera pas éliminé, de sorte que le handle qu'il utilise restera toujours ouvert. Finalement, le GC le collectera et appellera son finalizer, moment auquel il sera libéré correctement. Si vous souhaitez que les deux objets soient "nettoyés" correctement, vous devrez les éliminer tous les deux, soit en les enveloppant dans des instructions, soit en appelant Dispose manuellement.

Il est l'alternative, la syntaxe potentiellement plus propre ainsi:

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

Si vous faites cela, obj1 ET obj2 seront tous deux disposés à l'extrémité du bloc. Dans votre cas, cela signifie que les deux objets seront fermés et que leurs poignées seront libérées. Le GC les nettoiera ensuite lors d'une future collecte des ordures.

Pour plus de détails, voir MSDN's page on using.

Questions connexes