Question

Je comprends qu'il est utilisé pour désallouer des ressources non gérées. Toutefois, je ne comprends pas très bien quand Dispose est appelé. Je sais qu'il est appelé à la fin d'un bloc en utilisant , mais est-il également appelé lorsque l'objet est nettoyé?

Était-ce utile?

La solution

Si vous implémentez correctement IDisposable, vous devez également inclure un finaliseur qui appellera Dispose () sur votre objet.

Si vous faites cela, il sera appelé par le GC. Cependant, c’est toujours une TRÈS bonne idée d’essayer de toujours disposer de ces objets vous-même.

Le plus gros problème lorsque vous utilisez le finaliseur pour appeler Dispose, c’est que cela se produira dans un autre thread que vous ne contrôlez pas. Cela peut avoir des conséquences désagréables dans certaines situations, notamment provoquer une exception qui se produit dans le thread GC, ce qui n’est pas bon, ainsi que le fait de vérifier un champ disposé. Cela fait également partie des raisons pour lesquelles inclure GC.SuppressFinalize (this) dans votre méthode Dispose () est important: une fois qu'un objet est supprimé, vous ne souhaitez plus le supprimer.

Autres conseils

Dispose est appelé à plusieurs endroits:

  1. À la fin d'un bloc using.
  2. Lorsqu’il est explicitement appelé (dans un essai {} finally {} par exemple.)

Il est recommandé de l'appeler vous-même lorsque vous avez terminé avec une ressource afin de mieux gérer les ressources.

EDIT: Je me suis trompé. Dispose n'est PAS appelé lors de la récupération de place. Voir cet article.

Non, il n'est pas appelé lorsque l'objet est nettoyé. Si vous voulez ce comportement, vous pouvez utiliser le destructeur (finaliseur) et l'appel Dispose () à partir de là.

Comme vous le dites, il est appelé automatiquement et la fin d’un bloc utilisant .

Dispose () est appelé à la fin du bloc Using afin que vous puissiez compter sur les actions Dispose (par exemple, la fermeture d'une connexion à une base de données) pour avoir lieu lorsque l'objet sort de la portée. Aussi simple que cela.

Mise à jour: il n'y a rien de spécifique aux ressources non gérées dans un appel à Dispose (bien que ce soit une utilisation courante).

Mise à jour 2 : Reed Copsey a lancé un débat qui est utile pour comprendre IDisposable. Je recommande vivement cet article aux personnes désirant en savoir plus.

En résumé, une classe IDisposable vous permet de gérer explicitement la désallocation de ressources (généralement des ressources non gérées ou des connexions à une base de données) via la méthode Dispose (). Les instances de classe IDisposable doivent être créées dans un répertoire " Utilisation de " bloquer afin de s'assurer que la méthode Dispose est effectivement appelée. Si vous ne parvenez pas à le faire (ou à l'appeler explicitement dans un bloc "finalement", etc.), votre méthode Dispose ne sera pas appelée et les objets que vous souhaitez nettoyer seront orphelins. Dans tous les cas, je place les classes Jetables dans Utiliser des blocs et vous devriez aussi.

Vous pouvez également gérer le nettoyage des ressources dans un Finalizer (une classe Destructor). Ce sera appelé automatiquement lorsque la classe est GC'd. Les inconvénients de cette approche sont que vous ne contrôlerez pas explicitement les objets lorsque ceux-ci seront nettoyés et que vous devrez résoudre certains problèmes de threading. Ainsi, par exemple, les problèmes dans Destructors sont très difficiles à résoudre, car ils sont appelés de manière asynchrone et dans un autre thread. Le seul avantage est que vous n'avez pas à vous rappeler d'appeler votre destructeur comme vous le faites. Bien sûr, si vous utilisez toujours l'utilisation de blocs, il ne s'agit pas d'un problème.

NOTE: Ktrauberman, Reed et Pontus ont expliqué comment vous pouvez éviter les points que je soulève ci-dessous. C'est ce que je fais, mais je ne peux pas dire que c'est la seule façon de faire les choses. En effet, Microsoft recommande même d’appeler Dispose () depuis votre Finalizer dans certains cas. Cependant, je laisserai la discussion ici juste pour illustrer pourquoi il est important de suivre le conseil de Reed concernant la prudence lors du mélange de Destructors et de Dispose ().

Là où je ne suis pas d’accord avec la réponse de Reed, c’est dans l’affirmation que vous devez implémenter une classe IDisposable en appelant Dispose () dans votre Finalizer. Cela ne fait que confondre les deux constructions différentes et pourrait bien entraîner des problèmes. Par exemple, si vous créez votre instance de classe IDisposable dans un bloc Using et , vous appelez Dispose () dans Destructor, elle sera appelée deux fois - avec des plantages potentiellement désagréables et difficiles à déboguer ( ne contrôle pas le timing de GC). (Remarque: c'est vrai pour les destructeurs en général - ils peuvent, dans certaines circonstances, être appelés plus d'une fois!)

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