Destruction d'objets ? [Résolu] [C#] - C#/.NET managed - Programmation
Marsh Posté le 13-04-2005 à 10:09:48
Parce que la méthode Dispose de l'interface IDisposable ne sert qu'a libérer les ressources utilisées par une classe. En général, ça ne sert QUE pour libérer les ressources non-managées. En pratique, on liberera aussi les membres qui implémentent IDisposable.
Sinon tu peux manuellement mettre b à null, vu que Dispose ne le fait pas. Enfin, pour l'histoire du Close, c'est en général plus logique d'appeller Close que Dispose sur certains objets, alors Microsoft préconise d'implémenter une méthode Close qui fait directement appel à Dispose
Marsh Posté le 13-04-2005 à 10:40:48
FlorentG a écrit : Parce que la méthode Dispose de l'interface IDisposable ne sert qu'a libérer les ressources utilisées par une classe. En général, ça ne sert QUE pour libérer les ressources non-managées. En pratique, on liberera aussi les membres qui implémentent IDisposable. |
J'avais lu quelque chose allant dans ce sens mais je ne suis pas sûr de la méthode...
Si je comprend bien, dans mathode Dicpose) de la classe en cours de fermeture il faut appeler la méthode Dispose pour chaque membre implémentant IDisposable ?
Et de même lorsque je cesse d'utiliser un objet (implémentant IDisposable) pour le remplacer par un autre, je dois appeler Dispose là aussi ?
FlorentG a écrit : Sinon tu peux manuellement mettre b à null, vu que Dispose ne le fait pas. Enfin, pour l'histoire du Close, c'est en général plus logique d'appeller Close que Dispose sur certains objets, alors Microsoft préconise d'implémenter une méthode Close qui fait directement appel à Dispose |
Mais il y a un hic dans le comportement de C# : pourquoi lorsque ma Form b est visible Close appelle Dispose et ne le fait pas lorsque b est caché via b.Hide(); ???
J'ai contourné la fifficulté en utilisant b.IsDisposed en appelant manuellement b.Dispose() lors de la fermeture...
Marsh Posté le 13-04-2005 à 10:48:25
Gaxx a écrit : J'avais lu quelque chose allant dans ce sens mais je ne suis pas sûr de la méthode... |
Si tu n'appelle pas Dispose, alors certaines ressources non-managées ne seront pas explicitement libérées. Ca veut dire qu'elles seront libérées via le Finalizer, ce qui est à chier.
Gaxx a écrit : Mais il y a un hic dans le comportement de C# : pourquoi lorsque ma Form b est visible Close appelle Dispose et ne le fait pas lorsque b est caché via b.Hide(); ??? |
Qui dis Hide dis Show Donc quand tu la planques, ça veut peut-être dire que tu veux la réafficher plus tard, donc on ne la Dispose pas
Marsh Posté le 13-04-2005 à 10:59:02
FlorentG a écrit : Si tu n'appelle pas Dispose, alors certaines ressources non-managées ne seront pas explicitement libérées. Ca veut dire qu'elles seront libérées via le Finalizer, ce qui est à chier. |
C'est noté... Mais il va falloir que je vérifie toutes mes classes ...
FlorentG a écrit : Qui dis Hide dis Show Donc quand tu la planques, ça veut peut-être dire que tu veux la réafficher plus tard, donc on ne la Dispose pas |
Vi tant qu'on ne la ferme pas ok, mais si on ferme un objet caché c'est qu'on en a plus besoin...
En fait c'est ma fenêtre de loggin qui me sert de références pour connaître l'utilisateur, les chemins de bdd, ... Donc après validation je le garde ouverte mais cachée
Et lorsque l'utilisateur veut se déconnecter je ferme toutes les fenêtres via la méthode Close.
Je pense que la bas de mon problème est que je n'ai pas fait de programmation purement objet et mes fonction métier sont dans mes classes Form...
Je prend le devant des critiques : je sais que c'est pas bien
Marsh Posté le 13-04-2005 à 11:04:15
En fait la méthode Close n'appel pas directement la méthode Dispose :
public void Close() |
Donc quand tu voyage dans les méandres du truc, ça passe par des messages, des vérifs d'états, etc... Donc faut appeller dispose manuellement
Marsh Posté le 13-04-2005 à 11:11:20
Un petit pâté de NRaynaud :
nraynaud a écrit : il n'existe pas de destruction en C#, mais une finalisation. |
Marsh Posté le 13-04-2005 à 11:12:59
Enfin après ça dépend si l'objet peut être 'résurrecté', donc être réutilisé après un Dispose.
Marsh Posté le 13-04-2005 à 11:53:54
FlorentG a écrit : Enfin après ça dépend si l'objet peut être 'résurrecté', donc être réutilisé après un Dispose. |
Le dispose doit empécher la réutilisation :
Citation : initialize() et Dispose() sont des opérations qui ne peuvent être appellées qu'une fois dans la vie de l'objet. |
Maintenant je comprend pourquoi l'objet était toujours accessible.
Merci pour toutes les infos.
Marsh Posté le 13-04-2005 à 12:01:49
Presque :
Citation : Si la méthode Dispose d'un objet est appelée plus d'une fois, l'objet doit ignorer tous les appels autres que le premier. |
Mais on peut faire aussi des objets qui reviennent à la vie après un dispose
Marsh Posté le 13-04-2005 à 12:13:10
FlorentG a écrit : Presque :
|
Je ne veut pas de zombis dans mon appli moi ...
Open et Close ne font que de l'allocation et de la désallocation de variables managées.
Dispose place l'objet dans le garbage collector, et donc on peut le sortir de son cercueil.
Et l'appel à Finalize détruit complètement l'objet.
C'est bien ça ?
Marsh Posté le 13-04-2005 à 13:41:43
Finalize est appelé automatiquement par le GC. Ce qui est merdique. Si t'as un objet qui contient des ressources non managées, et que t'appelle pas dispose, alors ces ressources vont survire au moins une garbage collection, puis enfin le GC va appeler Finalize. Donc ça garde des objets en mémoire alors que ça devrait pas, etc. Donc t'as interêt à toujours utiliser la méthode Dispose, ce qui, en général, supprime la finalization.
Pour ce qui est de Open et Close, ça dépend de l'objet. Certaines classes, dans leur méthode Close, ne font pas appel à dispose
Marsh Posté le 13-04-2005 à 15:56:19
Florentg > j'ai expliqué pourquoi, il faut que les objets re-ouvrable puissent survivre.
Marsh Posté le 13-04-2005 à 10:04:30
Bonjour,
Je fais une application utilisant plusieurs fenêtres. Dans une Form A j'instancie une Form B lorsque l'utilisateur clique sur un bouton, et je ne veut qu'une instance de ma classe B.
class A:Form{
B b;
...
}
Je ne suis pas vraiment familiarisé avec la destruction d'objets en C# mais lorsque je ferme la Form B (bouton fermeture), il y a appel à b.Close(); et implicitement b.Dispose();.
Pour moi à ce stade A.b devrait être détruit !
Mais A.b n'est pas à null... Et j'ai toujours accès aux variables de b (exemple b.text) en lecture et en écriture
En fait mon test b==null devait me permettre de savoir si je devais ouvrir une nouvelle instance de B ou pas. J'ai trouvé une variable qui peut m'aider : b.IsDisposed.
Mais là j'ai eu encore une surprise : l'appel à b.Close(); implique l'appel à b.Dispose(); si b est visible mais pas si b est caché ...
Là je n'y comprends plus rien ! Il me semblait que l'appel à b.Close(); impliquait systématiquement l'appel à b.Dispose();
Pourquoi l'accès à b.Text ne lève pas d'exception et pourquoi A.b n'est pas à null.
Si quelqu'un peut m'expliquer les méchanismes de destruction en C# ou me donner un lien, ce serai sympa.
Gaxx
Message édité par Gaxx le 13-04-2005 à 11:54:11