À quoi sert IDisposable?
si .NET a la collecte des ordures alors pourquoi devez-vous appeler explicitement IDisposable
?
6 réponses
la collecte des ordures est pour la mémoire. Vous devez disposer de ressources non-mémoire - poignées de fichiers, sockets, poignées GDI+, connexions de base de données, etc. C'est typiquement ce qui sous-tend un IDisposable
type, bien que la poignée réelle peut être un assez long chemin dans une chaîne de références. Par exemple, vous pouvez Dispose
XmlWriter
qui dispose d'un StreamWriter
il y a une référence à, ce qui élimine le FileStream
contient une référence à, qui libère le gestionnaire de fichier lui-même.
Étendre un peu sur les autres commentaires:
la méthode Dispose() doit être utilisée pour tous les objets qui font référence à des ressources non gérées. Il peut s'agir, par exemple, de flux de fichiers, de connexions à des bases de données, etc. Une règle de base qui fonctionne la plupart du temps est: "si L'objet.net implémente IDisposable, alors vous devez appeler Dispose() lorsque vous avez terminé avec l'objet.
Cependant, quelques autres choses à garder à l'esprit:
- Appeler dispose ne pas vous pouvez contrôler lorsque l'objet est détruit et la mémoire libérée. Le GC gère ça pour nous et le fait mieux que nous ne le pouvons.
- Dispose nettoie toutes les ressources natives, tout au long de la pile de classes de base comme Jon l'a indiqué. Puis il appelle SuppressFinalize () pour indiquer que l'objet est prêt à être récupéré et qu'aucun travail supplémentaire n'est nécessaire. La prochaine course du GC nettoiera tout ça.
- si Dispose n'est pas appelé, alors GC trouve que l'objet doit être nettoyé, mais la mise au point doit être faite d'abord, pour s'assurer que les ressources sont libérées, que la demande de mise au point est mise en file d'attente et que le GC va de l'avant, de sorte que l'absence d'un appel pour disposer oblige un GC de plus à courir avant que l'objet puisse être nettoyé. Cela fait en sorte que l'objet est promu à la prochaine "génération" de GC. Ce n'est peut-être pas une grosse affaire, mais dans une application soumise à une pression de mémoire, la promotion d'objets jusqu'à des générations supérieures de GC peut pousser une application à haute mémoire au-dessus du mur pour être un application hors de la mémoire.
N'implémentez pas IDisposable dans vos propres objets sauf si vous en avez absolument besoin. Des implémentations mal mises en œuvre ou inutiles peuvent en fait empirer les choses au lieu de les améliorer. Quelques bons conseils peuvent être trouvés ici:
mise en oeuvre d'une méthode D'élimination
Ou lire toute la section de MSDN sur la Collecte des Ordures
parce que les objets contiennent parfois des ressources à côté de la mémoire. Le GC libère la mémoire; IDisposable permet de libérer n'importe quoi d'autre.
parce que vous souhaitez contrôler quand les ressources détenues par votre objet sera nettoyé.
voir, GC fonctionne, mais il le fait quand il se sent comme il, et même alors, les finaliseurs que vous ajoutez à vos objets seront appelés seulement après 2 collections GC. Parfois, vous voulez nettoyer ces objets immédiatement.
C'est quand IDisposable est utilisé. En appelant Dispose () explicitement (ou en utilisant le sucre syntaxique d'un bloc d'utilisation) vous pouvez accéder à votre objet se nettoyer de manière standard (c'est-à-dire que vous auriez pu implémenter votre propre appel cleanup() et l'appeler explicitement à la place)
exemples de ressources que vous souhaitez nettoyer immédiatement: les poignées de base de données, les poignées de fichiers, les poignées réseau.
afin d'utiliser le mot-clé using l'objet doit implémenter IDisposable. http://msdn.microsoft.com/en-us/library/yh598w02(SV.71).aspx
IDisposable
l'interface est souvent décrite en termes de ressources, mais la plupart de ces descriptions ne tiennent pas vraiment compte de ce que" ressource " signifie réellement.
Certains objets doivent demander à des entités extérieures de faire quelque chose en leur nom, au détriment d'autres entités, jusqu'à nouvel ordre. Par exemple, un objet englobant un flux de fichiers peut avoir besoin de demander à un système de fichiers (qui peut être n'importe où dans l'univers connecté) d'accorder un accès exclusif à un fichier. Dans de nombreux cas, l' le besoin de l'objet pour l'entité extérieure sera lié au besoin du code extérieur pour l'objet. Une fois que le code client a fait tout ce qu'il va faire avec l'objet file stream susmentionné, par exemple, cet objet n'aura plus besoin d'avoir un accès exclusif (ou n'importe quel accès d'ailleurs) à son fichier associé.
en général, un objet X qui demande à une entité de faire quelque chose jusqu'à nouvel ordre engage une obligation de remettre un tel avis, mais ne peut pas le faire tant que X client X services. Le but de IDisposable
est de fournir une façon uniforme de faire savoir aux objets que leurs services ne seront plus requis, afin qu'ils puissent aviser les entités (le cas échéant) qui agissaient en leur nom que leurs les services ne sont plus requis. Le code qui appelle IDisposable
n'ont besoin ni de savoir ni de se soucier des services (le cas échéant) qu'un objet a demandés à des entités externes, puisque IDisposable
invite simplement un objet à remplir des obligations (si tout) à des entités externes.
pour mettre les choses en termes de" ressources", un objet acquiert une ressource lorsqu'il demande à une entité extérieure de faire quelque chose pour son compte (généralement, mais pas nécessairement, en accordant l'usage exclusif de quelque chose) jusqu'à nouvel ordre, et libère une ressource lorsqu'il dit à une entité extérieure que ses services ne sont plus nécessaires. Le Code qui acquiert une ressource ne gagne pas une "chose" autant qu'il engage une obligation; libérer une ressource n'abandonne pas une "chose", mais au lieu de cela remplit une obligation.