IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Windows Forms Discussion :

Mieux Coder: Corriger les fuites


Sujet :

Windows Forms

  1. #1
    Membre du Club
    Inscrit en
    Mai 2009
    Messages
    172
    Détails du profil
    Informations forums :
    Inscription : Mai 2009
    Messages : 172
    Points : 49
    Points
    49
    Par défaut Mieux Coder: Corriger les fuites
    Bonjour à tous, suite à un énième:
    Erreur lors de la création d'un Handler de fenêtre
    Je viens vous demander de m'aider à remettre en question ma manière coder, en gros il faut libérer la mémoire dés qu'on utilise plus une variable c'est ça?

    Car j'ai du mal avec .net profiler ou encore dottrace, je vous demande quels sont les points principaux dans la manière de coder pour éviter ce genre d'erreurs?
    Depuis quelques temps, je m'efforce de mettre des Dispose sur tout mes datareader et sur quelques autres variables. Ou faut -il également els placer?

    Que rajouter d'autres?

    Mon erreur apparait dans une fonction (assez longue et complexe qui crée un calendrier avec 20 personnes sur match aller retour) et ensuite je lui demande de supprimer le controle de chargement (qui se rajoute par dessus en attendant que ça soit finit) et d'afficher l'usercontrol de la page d'accueil (qui récupère les dernières news à son chargement).

    Le debuggueur bug ici, dan smon form1.designer:


    L'erreur que le debuggueur renvoie:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
            protected override void Dispose(bool disposing)
            {
                if (disposing && (components != null))
                {
                    components.Dispose();
                }
                base.Dispose(disposing);
            }
    System.NullReferenceException was unhandled by user code
    Message=La référence d'objet n'est pas définie à une instance d'un objet.
    Source=System.Windows.Forms
    StackTrace:
    à System.Windows.Forms.ListView.OnHandleDestroyed(EventArgs e)
    à System.Windows.Forms.Control.WmDestroy(Message& m)
    à System.Windows.Forms.Control.WndProc(Message& m)
    à System.Windows.Forms.ListView.WndProc(Message& m)
    à System.Windows.Forms.Control.ControlNativeWindow.OnMessage(Message& m)
    à System.Windows.Forms.Control.ControlNativeWindow.WndProc(Message& m)
    à System.Windows.Forms.NativeWindow.DebuggableCallback(IntPtr hWnd, Int32 msg, IntPtr wparam, IntPtr lparam)
    à System.Windows.Forms.UnsafeNativeMethods.IntDestroyWindow(HandleRef hWnd)
    à System.Windows.Forms.UnsafeNativeMethods.DestroyWindow(HandleRef hWnd)
    à System.Windows.Forms.NativeWindow.DestroyHandle()
    à System.Windows.Forms.Control.DestroyHandle()
    à System.Windows.Forms.Control.Dispose(Boolean disposing)
    à System.Windows.Forms.ContainerControl.Dispose(Boolean disposing)
    à System.Windows.Forms.Form.Dispose(Boolean disposing)
    à BM2010.frmSaisiesBoutons.Dispose(Boolean disposing) dans C:\Users\Victor\Documents\PROG\PROJET BASKET MANAGER\CODE\C#\BM2010\BM2010\Form1.Designer.cs:ligne 20
    à System.ComponentModel.Component.Dispose()
    à System.Windows.Forms.ApplicationContext.Dispose(Boolean disposing)
    à System.Windows.Forms.Application.ThreadContext.DisposeThreadWindows()
    InnerException:
    Mais l'erreur apparait également lorsque je lance mon application (je récupère également les news au chargement) et dans les deux cas l'user control des news ne se charge qu'à moitié, j'en déduis que ça vient de là mais alors pouvez vous me dire ce que j'ai fait pour que ça plante?
    Parce que j'imagine que ce genre d'erreurs est récurrent, peut etre n'avez vous pas besoin de mon code.

    D'après mes recherches c'est juste que trop de trucs se chargent en meme temps mais je fais comment pour charger autrement?

    Pour mon code je sais pas lequel poster parce qu'en fait j'ai une listview et un tableau, et seul la listview se charge donc ça peut venir du designer non?

    Voilà, ce post a donc double vocation, à savoir m'aider à comprendre comment coder plus proprement mais également pour résoudre ce problème qui apparait assez fréquemment.

    Merci d'avance, r0seBa

  2. #2
    Membre habitué
    Profil pro
    Inscrit en
    Août 2005
    Messages
    150
    Détails du profil
    Informations personnelles :
    Âge : 37
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Août 2005
    Messages : 150
    Points : 152
    Points
    152
    Par défaut
    Le problème semble venir d'un objet null.

    Il faut absolument prendre l'habitude de tester les objets que tu utilise, surtout quand ces derniers sont charger via des sources externes.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    object obj = maClass.GetNews();
    if(obj != null)
    {
    //Je peux travailler avec mon objet
    }

  3. #3
    Membre du Club
    Inscrit en
    Mai 2009
    Messages
    172
    Détails du profil
    Informations forums :
    Inscription : Mai 2009
    Messages : 172
    Points : 49
    Points
    49
    Par défaut
    LE problème peut en effet venir de là puisque j'utilise la meme variable pour mon objet (c'est peut etre pas la meilleure solution en fait): Je l'ai déclaré en statique au début de mon code.

    Je sais pas si c'est la meilleure solution vu que si je fais ça pour toutes les pages ça fait beaucoup.


    En fait je vois pas comment il pourrait être null parce que pour le moment je faisais ça pour après avoir créé le calendrier:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
     
     this.Controls.Remove(chargement);
                        chargement.Dispose();
     
                        panel1.Controls.Clear();
                        this.accueil_titre.Text = RM.GetString("ACCUEIL_MESSAGERIE");
                        if (show_messagerie == null)
                        {
                            show_messagerie = new messagerie();
                        }
                        show_messagerie.Location = new Point(0, 0);
                        show_messagerie.Dock = DockStyle.Fill;
     
                        panel1.Controls.Add(show_messagerie);
    avec show_messagerie déclaré comme suit au début de mon code:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    public static messagerie show_messagerie;
    Merci

  4. #4
    Membre du Club
    Inscrit en
    Mai 2009
    Messages
    172
    Détails du profil
    Informations forums :
    Inscription : Mai 2009
    Messages : 172
    Points : 49
    Points
    49
    Par défaut
    Vous pensez que ça vient de mon control, des taches que j'effectue dedans? ou de la manière de l'ajouter?

    J'arrive vraiment pas à corriger ce bug :s

  5. #5
    Membre émérite Avatar de Guulh
    Homme Profil pro
    Inscrit en
    Septembre 2007
    Messages
    2 160
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Septembre 2007
    Messages : 2 160
    Points : 2 925
    Points
    2 925
    Par défaut
    Citation Envoyé par r0seBa Voir le message
    Depuis quelques temps, je m'efforce de mettre des Dispose sur tout mes datareader et sur quelques autres variables. Ou faut -il également els placer?
    Dès que t'as fini de t'en servir. Une façon simple de coder en Ado.Net est la suivante :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    using (DbConnection conn = gnagna.CreateConnection())
    {
      conn.Open();
      using(DBCommand cmd = conn.CreateCommand())
      {
         cmd.CommandText = "select bidule from truc";
         using(DbDataReader reader = cmd.ExecuteNonQuery())
         {
         }
      }
    }
    Le mot clé using t'assure que la méthode de l'objet en question sera bien appelée à la sortie du bloc, y compris en cas d'exception.

    Donc : OUI, dès que tu crées une instance d'une classe IDisposable, il faudra à un moment appeler Dispose. Soit explicitement, soit en le mettant dans un bloc "using".

    our ton cas particuliers des forms : le designer de forms crée une variable privée nommée components. Si tu rajoutes un objet là dedans, il sera disposé en même temps que la form.
    ಠ_ಠ

  6. #6
    Membre du Club
    Inscrit en
    Mai 2009
    Messages
    172
    Détails du profil
    Informations forums :
    Inscription : Mai 2009
    Messages : 172
    Points : 49
    Points
    49
    Par défaut
    Bonjour, merci de ta réponse.

    Mais alors d'après tes explications ça veut dire que si je met Dispose() c'est équivalent? donc au final ça ne résoud pas mon problème, même si ça répond parfaitement à ma question pour coder plus proprement, je tacherais d'essayer de m'en servir. Merci

    EN utilisant le débuggueur je trouve l'erreur ici:
    EDIT: Finalement elle est pas là je réédite mon message dés que j'ai trouvé d'ou elle venait

  7. #7
    Expert éminent sénior

    Avatar de Philippe Vialatte
    Homme Profil pro
    Architecte technique
    Inscrit en
    Juillet 2004
    Messages
    3 029
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 45
    Localisation : France, Alpes Maritimes (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Architecte technique
    Secteur : High Tech - Produits et services télécom et Internet

    Informations forums :
    Inscription : Juillet 2004
    Messages : 3 029
    Points : 12 465
    Points
    12 465
    Par défaut
    bon, mes 2 cts.

    Mon erreur apparait dans une fonction (assez longue et complexe qui crée un calendrier avec 20 personnes sur match aller retour) et ensuite je lui demande de supprimer le controle de chargement (qui se rajoute par dessus en attendant que ça soit finit) et d'afficher l'usercontrol de la page d'accueil (qui récupère les dernières news à son chargement).
    Si la fonction est longue est complexe, splitte la en plusieurs sous-fonctions moins longues et complexes, pense SRP...ca te permettra de suivre plus facilement le cycle de vie de tes objets...

    LE problème peut en effet venir de là puisque j'utilise la meme variable pour mon objet (c'est peut etre pas la meilleure solution en fait): Je l'ai déclaré en statique au début de mon code.
    Mal ! On est en .Net, pas en C .
    Une bonne pratique est de déclarer tes variables le plus prés possible de l'endroit ou tu les utilise.

    Pour ton problème, le plus simple, c'est de commencer par commenter tout ton code, et dé-commenter au fur et à mesure

    Si tu as un controleur de code source (j'espère pour toi...), tu tagges ton fichier courant, et comme ca tu n'as pas de risque

    Mon Blog

    The Cake is still a lie !!!



    Vous voulez contribuer à la rubrique .NET ? Contactez-moi par MP.
    Vous voulez rédiger des articles pour la rubrique .NET ? Voici la procédure à suivre.

Discussions similaires

  1. [MFC] Comment corriger ces fuites de mémoire
    Par Philippe320 dans le forum MFC
    Réponses: 8
    Dernier message: 07/03/2006, 13h50
  2. Formulaire: permettre de corriger les données
    Par Dino501 dans le forum ASP
    Réponses: 5
    Dernier message: 22/02/2006, 17h36
  3. Traquer les fuites mémoires (memoryLeak) ?
    Par MonsieurAk dans le forum Windows
    Réponses: 2
    Dernier message: 08/09/2005, 09h07
  4. Les fuites de la mémoire!!!!!!!!
    Par pointer dans le forum Langage
    Réponses: 5
    Dernier message: 07/09/2005, 14h30
  5. Réponses: 8
    Dernier message: 17/10/2002, 12h52

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo