Question

Si .NET a un garbage collection, pourquoi devez-vous appeler explicitement IDisposable ?

Était-ce utile?

La solution

La récupération de place est pour la mémoire. Vous devez disposer de ressources autres que de la mémoire - descripteurs de fichier, sockets, descripteurs GDI +, connexions à une base de données, etc. C'est généralement ce qui sous-tend un type IDisposable , bien que le descripteur réel puisse être assez long dans une chaîne de références. Par exemple, vous pouvez Dispose un XmlWriter qui élimine un StreamWriter auquel il renvoie, qui élimine le FileStream . it a une référence à, qui libère le descripteur de fichier lui-même.

Autres conseils

Développer un peu d'autres commentaires:

La méthode Dispose () doit être appelée sur tous les objets comportant des références à des ressources non gérées. Parmi les exemples, citons les flux de fichiers, les connexions à la base de données, etc.

Toutefois, il convient de garder à l’esprit les autres points suivants:

  • L'appel de disposition ne vous permet pas de contrôler le moment où l'objet est réellement détruit et la mémoire libérée. GC gère cela pour nous et le fait mieux que nous ne le pouvons.
  • Dispose nettoie toutes les ressources natives jusqu'à la pile de classes de base, comme indiqué par Jon. Ensuite, 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. Le prochain cycle du GC va le nettoyer.
  • Si Dispose n'est pas appelé, alors le CP considère que l'objet doit être nettoyé, mais Finalize doit être appelé en premier. Pour s'assurer que les ressources sont libérées, cette demande de Finalisation est mise en file d'attente et le GC continue. L'absence d'appel à Dispose oblige un autre CPG à s'exécuter avant que l'objet ne puisse être nettoyé. Cela provoque la promotion de l'objet à la "génération suivante". de GC. Cela peut sembler banal, mais dans une application soumise à des contraintes de mémoire, la promotion d'objets jusqu'à des générations supérieures de GC peut pousser une application à mémoire vive sur le mur à une application épuisée.
  • 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 réalité aggraver les choses au lieu de s'améliorer. Quelques bonnes indications peuvent être trouvées ici:

    Implémentation d'une méthode d'élimination

    Ou lisez l'intégralité de la section de MSDN relative au nettoyage de la mémoire

Parce que les objets contiennent parfois des ressources à côté de la mémoire. GC libère la mémoire; Identifiable, vous pouvez libérer tout le reste.

parce que vous souhaitez contrôler le moment où les ressources de votre objet seront nettoyées.

Vous voyez, GC fonctionne, mais il le fait quand bon vous semble, et même dans ce cas, les finaliseurs que vous ajoutez à vos objets ne seront appelés qu'après 2 collections GC. Parfois, vous voulez nettoyer ces objets immédiatement.

Ceci est le cas où IDisposable est utilisé. En appelant explicitement Dispose () (ou en utilisant le sucre syntaxique d’un bloc using), vous pouvez accéder à votre objet pour le nettoyer de manière standard (c’est-à-dire que vous auriez pu implémenter votre propre appel cleanup () et l’appeler explicitement à la place).

Les exemples de ressources que vous souhaitez nettoyer immédiatement sont les suivants: descripteurs de base de données, descripteurs de fichier, descripteurs réseau.

Pour utiliser le mot-clé using, l'objet doit implémenter IDisposable. http://msdn.microsoft.com/en-us /library/yh598w02(VS.71).aspx

L’interface IDisposable est souvent décrite en termes de ressources, mais la plupart de ces descriptions ne tiennent pas vraiment compte de la "ressource". signifie vraiment.

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 situé n'importe où dans l'univers connecté) d'accorder un accès exclusif à un fichier. Dans de nombreux cas, 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 de flux de fichiers susmentionné, par exemple, cet objet n'aura plus besoin d'avoir un accès exclusif (ou un accès quelconque) au fichier associé.

En général, un objet X qui demande à une entité de faire quelque chose jusqu'à nouvel ordre entraîne l'obligation de remettre un tel avis, mais ne peut pas le faire tant que le client de X peut avoir besoin des services de X. Le but de IDisposable est de fournir un moyen uniforme de faire savoir aux objets que leurs services ne seront plus nécessaires, afin qu'ils puissent notifier aux entités (le cas échéant) qui agissaient en leur nom que leurs services ne sont plus nécessaires. Le code qui appelle IDisposable n'a pas besoin de savoir ni de se soucier des services (le cas échéant) qu'un objet a demandés à des entités extérieures, car IDisposable invite simplement un objet à remplir ses obligations (si tout) vers des entités extérieures.

En termes de "ressources", un objet acquiert une ressource lorsqu'il demande à une entité externe de faire quelque chose en son nom (généralement, mais pas nécessairement, en accordant l'utilisation exclusive de quelque chose) jusqu'à nouvel ordre, et libère une ressource lorsqu'elle indique à une entité extérieure que ses services ne sont plus nécessaires. Le code qui acquiert une ressource ne gagne pas de "chose". autant qu'il engage une obligation; libérer une ressource n'abandonne pas une "chose", mais remplit une obligation.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top