Forum |  HardWare.fr | News | Articles | PC | S'identifier | S'inscrire | Shop Recherche
1513 connectés 

  FORUM HardWare.fr
  Programmation
  C#/.NET managed

  destruction en règle d'un objet perso en .NET

 


 Mot :   Pseudo :  
 
Bas de page
Auteur Sujet :

destruction en règle d'un objet perso en .NET

n°1535928
Celiphane
Posté le 29-03-2007 à 16:32:00  profilanswer
 

Hello tout le monde,
 
Voilà j'ai une lacune à combler en VB.NET (ou .net en général).
Dans une appli, j'instancie une class de ma conception (qui contient divers autres objets comme des timers, des sockets etc), elle devient donc un objet et pour le garder en vie une fois sortie de la procédure qui l'a créé, je l'ajoute dans une collection d'objet (qui est public).
 
Cependant je ne sais pas comment détruire cet objet lorsque je n'en ai plus besoin.
En effet je pensais que le fait de supprimer l'objet de la collection suffirait à détruire le dernier pointeur existant et donc détruirait l'objet, mais une fois ceci fait, je constate via des points d'arrêt que les timers dans mon objet continue de se déclencher, ce qui prouve que l'objet vit toujours quelque part !
 
Merci de m'éclairer concernant ce concept, et de me dire comment faire afin que je puisse détruire définitivement mes objets.
 
Cordialement

mood
Publicité
Posté le 29-03-2007 à 16:32:00  profilanswer
 

n°1536001
MagicBuzz
Posté le 29-03-2007 à 17:39:22  profilanswer
 

essaie de lui affecter "null" (ou "nothing" en vb) avant de le supprimer de la collection.
 
vérifie aussi que tu arrêtes bien tes timers dans ton destructeur.
 
mais pour faire proprement, tu dois le faire dériver de IDisposable et ajouter une méthode public "Dispose()" qui effectue tout ce travail de nettoyage. (à ce moment, le destructeur fait un appel à Dispose() puis éventuellement détruit quelques petits bouts en plus)

n°1536033
Celiphane
Posté le 29-03-2007 à 18:35:30  profilanswer
 

Salut à toi et merci pour pour ton aide.
 
Lui affecter nothing ne sert n'aura servi à rien, si ce n'est qu'à détruire le pointeur auquel j'ai assigné nothing. L'objet lui, continue son chemin.
 
En revanche ta seconde proposition me semble très approprié !
Comment faire pour dériver ma class en IDisposable ?
Quand tu dis le destructeur fait un appel à Dispose(), c'est automatique ou c'est à moi d'appeler ma méthode public Dispose ?
 
Si je comprends bien donc, je dois donc faire le travail de nettoyage moi-même à l'intérieur même de ma classe. Toutefois si j'arrête à la mano les timers, comment saurais-je une fois qu'ils sont arrêtés, que la class est vraiment détruite ?
 
Quelqu'un peut-il me poster un exemple de ces sub dispose & compagnie ?
 
Merci beaucoup.

n°1536039
MagicBuzz
Posté le 29-03-2007 à 19:09:14  profilanswer
 

public class maClass : IDisposable
{
    object maVariable;
 
    public maClass()
    {
       maVariable = new ...;
    }
 
    public void Dispose()
    {
        if (maVariable != null)
        {
            maVariable.Dispose(); // Important pour un timer par exemple, qui pourraît bien s'autoréférencer ailleurs que dans ton objet, notamment parcequ'un timer tourne dans un thread séparé
            maVariable = null;
        }
    }
 
    ~maClass()
    {
        Dispose();
        // Eventuellement d'autres ménages
    }
}
 
 
maClass test = new maClass();
maCollection.Add(test);
maCollection[0].Dispose(); // Normalement, cette ligne est inutile, puisque le destructeur est censé être appelé
maCollection.RemoveAt(0);


Message édité par MagicBuzz le 29-03-2007 à 19:10:25
n°1536046
Tamahome
⭐⭐⭐⭐⭐
Posté le 29-03-2007 à 19:13:52  profilanswer
 

MagicBuzz a écrit :

essaie de lui affecter "null" (ou "nothing" en vb) avant de le supprimer de la collection.
 
vérifie aussi que tu arrêtes bien tes timers dans ton destructeur.
 
mais pour faire proprement, tu dois le faire dériver de IDisposable et ajouter une méthode public "Dispose()" qui effectue tout ce travail de nettoyage. (à ce moment, le destructeur fait un appel à Dispose() puis éventuellement détruit quelques petits bouts en plus)


 
ca implémente l'interface IDisposable, ca n'en dérive pas.

n°1536048
MagicBuzz
Posté le 29-03-2007 à 19:16:01  profilanswer
 

ouais, chuis pas trop fluent avec les dénomination :ange:
 
"tu fourres le truc dans le bidule et quand tu machine le bignou ça proutch" <= c'est tellement plus clair :D

n°1536164
Harkonnen
Modérateur
Un modo pour les bannir tous
Posté le 30-03-2007 à 00:03:51  profilanswer
 
n°1536209
Celiphane
Posté le 30-03-2007 à 09:25:19  profilanswer
 

Merci à tous pour vos explications !
 
 
Toutefois je me retrouve maintenant avec 2 solutions, mais laquelle choisir ?
Harkonnen m'a pointé vers le fonctionnement de Finalize qui est donc finalement la même chose plus ou moins que Dispose puisque j'y ferais le ménage.
 
Mais que faire ? Dispose ou Finalize ?
Le mieux niveau nettoyage, vitesse, ressource, c'est quoi ?
 
 
Merci encore.

n°1536213
MagicBuzz
Posté le 30-03-2007 à 09:29:10  profilanswer
 

Celiphane a écrit :

Merci à tous pour vos explications !
 
 
Toutefois je me retrouve maintenant avec 2 solutions, mais laquelle choisir ?
Harkonnen m'a pointé vers le fonctionnement de Finalize qui est donc finalement la même chose plus ou moins que Dispose puisque j'y ferais le ménage.
 
Mais que faire ? Dispose ou Finalize ?
Le mieux niveau nettoyage, vitesse, ressource, c'est quoi ?
 
 
Merci encore.


fait plus confiance à Harko (chieur :o) il a bien plus d'expérience que moi en ce qui concerne .NET ;)


Message édité par MagicBuzz le 30-03-2007 à 09:29:26
n°1536237
MagicBuzz
Posté le 30-03-2007 à 09:50:42  profilanswer
 

D'après ce lien : http://msdn2.microsoft.com/fr-fr/l [...] S.80).aspx
 
Je dirais en fait qu'Harko n'apporte pas une solution supplémentaire, mais des précisions.
 
Effectivement, en .NET il n'y a pas de "destructeur" à proprement parler si je pige bien l'article, mais une méthode surchargeable Finalize().
En C# et C++, on utilise une syntaxe de destructeur, mais en VB.NET et J#, qui n'ont pas de destructeurs, on doit fait un appel explicit à cette méthode.
 
C'est bien ça Harko ?
 
Toujours est-il que le "Dispose" est un "nice to have" à rajouter une fois que t'as un destructeur qui fait correctement son travail.
 
Et l'article qu'a filé Harko confirme ce que j'avais dit au début : effectivement, si on ne dit pas comment fermer un fichier au GC, il ne sait pas le faire tout seul.

mood
Publicité
Posté le 30-03-2007 à 09:50:42  profilanswer
 

n°1536239
MagicBuzz
Posté le 30-03-2007 à 09:52:04  profilanswer
 

Citation :


Remarques à l'attention des implémenteurs Object.Finalize n'a aucun effet par défaut. Il ne doit être substitué par une classe dérivée qu'en cas de nécessité, car toute récupération pendant une opération garbage collection dure bien plus longtemps si une opération Finalize doit être exécutée. Si Object contient des références à des ressources, Finalize doit être substitué par une classe dérivée afin de libérer ces ressources avant que Object soit ignoré pendant l'opération garbage collection. Un type doit implémenter Finalize s'il utilise des ressources non managées, telles que des handles de fichiers ou des connexions de bases de données, qui doivent être libérées en cas de récupération de l'objet managé qui les emploie. Pour un moyen complémentaire et plus contrôlable de détruire les ressources, consultez l'interface IDisposable. Finalize peut effectuer n'importe quelle action, y compris ressusciter (rendre à nouveau accessible) un objet qui a été nettoyé pendant une opération garbage collection. Cependant, l'objet ne peut être ressuscité qu'une seule fois. Finalize ne peut pas être appelé sur des objets ressuscités pendant une opération garbage collection.  

n°1536295
Harkonnen
Modérateur
Un modo pour les bannir tous
Posté le 30-03-2007 à 10:56:05  profilanswer
 

Celiphane a écrit :

Merci à tous pour vos explications !
 
 
Toutefois je me retrouve maintenant avec 2 solutions, mais laquelle choisir ?
Harkonnen m'a pointé vers le fonctionnement de Finalize qui est donc finalement la même chose plus ou moins que Dispose puisque j'y ferais le ménage.
 
Mais que faire ? Dispose ou Finalize ?
Le mieux niveau nettoyage, vitesse, ressource, c'est quoi ?
 
 
Merci encore.


Les méthodes Finalize sont appelées quand le GC collecte l'objet. Il vaut mieux éviter de créer des types Finalizables, pour les raisons suivantes :
- Tu n'as aucune idée du moment auquel la méthode sera appelée, et donc du moment auquel ton objet sera libéré
- Les objets Finalizables sont plus longs à créer car ils sont placés sur la liste de Finalization du GC
- Les objets Finalizables peuvent être promus dans des générations plus anciennes (en terme de GC), ce qui sollicite davantage la mémoire
- Un objet Finalizable peut avoir une référence sur un autre objet, augmentant ainsi inutilement sa durée de vie
- Le CLR ne te garantit pas l'ordre dans lequel les méthodes Finalize seront appelées pour des objets dépendants. Si par exemple tu as un objet qui contient une référence sur un autre objet, et que le GC détecte que ces 2 objets sont collectables, il est fort possible que l'objet pointé soit libéré avant l'objet qui le pointe, pouvant aboutir à des résultats imprévisibles...
 
La méthode Finalize est appelée par le GC dans les circonstances suivantes :
- La génération 0 de la mémoire est pleine
- Appel explicit à GC.Collect()
- Le CLR décharge un domaine d'Application
- Le CLR est en cours de fermeture
 
Si tu veux faire les choses proprement, alors tu dois implémenter le pattern Dispose.  
http://haacked.com/archive/2005/11 [...] ttern.aspx

n°1536299
Harkonnen
Modérateur
Un modo pour les bannir tous
Posté le 30-03-2007 à 10:59:10  profilanswer
 

MagicBuzz a écrit :


Effectivement, en .NET il n'y a pas de "destructeur" à proprement parler si je pige bien l'article, mais une méthode surchargeable Finalize().
En C# et C++, on utilise une syntaxe de destructeur, mais en VB.NET et J#, qui n'ont pas de destructeurs, on doit fait un appel explicit à cette méthode.
 
C'est bien ça Harko ?


Oui, sauf qu'il vaut mieux utiliser le pattern Dispose au lieu d'appeler explicitement Finalize()
 

MagicBuzz a écrit :


Et l'article qu'a filé Harko confirme ce que j'avais dit au début : effectivement, si on ne dit pas comment fermer un fichier au GC, il ne sait pas le faire tout seul.


Si, cf ma réponse au dessus :o

n°1536317
Celiphane
Posté le 30-03-2007 à 11:23:55  profilanswer
 

Merci.

n°1536385
MagicBuzz
Posté le 30-03-2007 à 13:52:00  profilanswer
 

Harkonnen a écrit :

Oui, sauf qu'il vaut mieux utiliser le pattern Dispose au lieu d'appeler explicitement Finalize()


=> Mouif, mais alors pkoi t'as mis un lien sur Finalize ? :D (/me n'a rien pigé, comme d'hab ;))
 

Harkonnen a écrit :

Si, cf ma réponse au dessus :o


=> Ouais, m'enfin ce que je voulais dire par "y sait pas faire", c'est qu'il peut aussi bien le détruire 1 ms après la destruction de l'objet appelant, tout comme il peut ne le détruire que 6 heures après.

n°1536399
Harkonnen
Modérateur
Un modo pour les bannir tous
Posté le 30-03-2007 à 14:06:48  profilanswer
 

MagicBuzz a écrit :

=> Mouif, mais alors pkoi t'as mis un lien sur Finalize ? :D (/me n'a rien pigé, comme d'hab ;))


me suis chié dessus dans mes favoris, je voulais mettre le lien que je lui ai posté sur Dispose :whistle:

n°1536402
MagicBuzz
Posté le 30-03-2007 à 14:08:35  profilanswer
 

arf :D je comprends mieux maintenant :lol:
 
(comment tu m'as trop embrouillé la tête :o genre dans le topic blabla, regarde-moi ce truc horrible que j'ai fait à cause de toi :D)


Message édité par MagicBuzz le 30-03-2007 à 14:09:26

Aller à :
Ajouter une réponse
  FORUM HardWare.fr
  Programmation
  C#/.NET managed

  destruction en règle d'un objet perso en .NET

 

Sujets relatifs
Projet d'installation .NET qui requiert install externeASP.NET structure table dataset
Problème de thread avec les sockets en .NETTester l'existence d'un objet
Lire des articles d'1 serveur sur 1 autre serveur?MSSQL& XML, PHP,.NETfaire bouger un objet
[VB.NET] Visual Basic 2005 express edition, limitations ?[VB.NET] Réccupérer la valeur du timer
ASP.NET DDE[ASP.NET] Accès Web Service via browser : parametres
Plus de sujets relatifs à : destruction en règle d'un objet perso en .NET


Copyright © 1997-2022 Hardware.fr SARL (Signaler un contenu illicite / Données personnelles) / Groupe LDLC / Shop HFR