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

C# Discussion :

.close ou .dispose pour une form


Sujet :

C#

  1. #1
    Membre émérite
    Profil pro
    Mangeur de gauffre
    Inscrit en
    Octobre 2007
    Messages
    4 413
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations professionnelles :
    Activité : Mangeur de gauffre

    Informations forums :
    Inscription : Octobre 2007
    Messages : 4 413
    Points : 2 498
    Points
    2 498
    Par défaut .close ou .dispose pour une form
    Bonjour

    J'apprends csharp et la POO sur le tas depuis janvier.
    Bien qu'ayant déja fait quelques appli tres fonctionelles, j'ai encore des tas de choses a apprendre

    Aujourd'hui je me heurte au concept de .close .dispose d'une form

    Quand je quite une form, j'ai pris l'habitude de faire un .close
    Je tombe maintenant sur un exemple faisant un .dispose

    Quelle est la différence ?
    Dans quel cas l'un ou l'autre est le plus approprié ?


    Et d'une maniere plus générale, dans quel cas faut il faire un dispose d'un objet instancié

    Exemple : je declare une datatable dans une fonction : doiss-je faire un dispose en quittant la fonction ?
    En vieil habitué du C je fais toujours des free de ce que j'alloue mais j'avais cru comprendre que Csharp avait un GC pour faire ca

    Merci pour vos conseils

  2. #2
    Membre confirmé
    Profil pro
    Inscrit en
    Janvier 2007
    Messages
    547
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2007
    Messages : 547
    Points : 627
    Points
    627
    Par défaut
    Salut Olibara,

    Déjà première règle, si la classe implémente IDisposable (comprendre expose la méthode Dispose()), tu dois t'en servir (on pourra discuter longuement du "sans ça marche aussi", mais si la classe en question doit etre disposée, c'est qu'il y a une raison).

    .Net possède un GC, certes mais un GC ne résout qu'une partie des problèmes de la logique de construction/destruction. Prenons un exemple simple en C++ :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    UneClass* c = new UneClass();
    //..
     
    delete c;
     
    //.. Les ressources de c sont libérées et la réacquisition est possible
    En admettant que c tient un handle sur un fichier en accès exclusif, tu es assuré que la destruction de c entrainera la fermeture de ce handle. Reprenons le meme exemple en C# :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    UneClass c = new UneClass();
    //..
    Tu es garanti que c sera détruit à un moment donné par le GC, mais tu ne peux pas contrôler ce moment. D'où la question : Comment libérer de manière explicite des ressources sans remettre en cause le design du GC (qui passe quand il le souhaite) ? C'est à cette problématique que répond le pattern disposable. En réécrivant le code en C#, on pourrait faire ceci :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    UneClass c = new UneClass();
    //..
    c.Dispose();
     
    ///////////////////////// équivalent à 
     
    using (UneClass c = new UneClass())
    {
        //scope de validité de c
    }
    En admettant que dans la méthode dispose de ta classe, tu fermes le handle vers le fichier, une fois cet appel fait, tu peux réacquérir ce fichier de manière certaine.

    Pour la différence entre close et dispose, elle sont conceptuellement assez proche, mais dans tous les cas, il faut faire du cas par cas en lisant la documentation des deux méthodes (Par exemple, pour une form, le comportement de close peut être différent suivant que la form soit modale (auquel cas le dispose n'est pas appelé en interne) ou non (le dispose sera appelé)).

    Pour la Datatable (comme pour tous les autres IDisposable), tu appelles Dispose une fois que tu es certain que tu ne te serviras plus de l'objet.

    Bref, il y a deux problèmes distincts; la gestion du pool de memoire (ca ce n'est pas ton problème, la mémoire sera toujours collectée à un moment ou un autre), et la gestion de la durée de vie des objets (qui etait proche de la gestion de la mémoire en C++, mais qui doit être désynchronisée en .Net (non déterminisme etc ...)).

    En esperant avoir été clair, bonne continuation. =)

    edit : Aurtaugraph

  3. #3
    Membre émérite
    Profil pro
    Mangeur de gauffre
    Inscrit en
    Octobre 2007
    Messages
    4 413
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations professionnelles :
    Activité : Mangeur de gauffre

    Informations forums :
    Inscription : Octobre 2007
    Messages : 4 413
    Points : 2 498
    Points
    2 498
    Par défaut
    Merci SirJulio d'avoir pris le temps et la patience pour cette belle explication

    C'est beaucoup plus clair !

  4. #4
    Expert éminent
    Avatar de StormimOn
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Mai 2005
    Messages
    2 593
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 46
    Localisation : France, Sarthe (Pays de la Loire)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mai 2005
    Messages : 2 593
    Points : 7 660
    Points
    7 660
    Par défaut
    Pour information, chose que j'ai apprise récemment, lorsque que l'on affiche un formulaire avec la méthode ShowDialog(), il faut appeler la méthode Dispose() pour libérer proprement les ressources.

    Si un formulaire est affiché sous la forme d'une boîte de dialogue modale, un clic sur le bouton Fermer (le bouton portant une X dans le coin supérieur droit du formulaire) masque le formulaire et affecte à la propriété DialogResult la valeur DialogResult.Cancel. À l'inverse de ce qui se passe pour les formulaires non modaux, la méthode Close n'est pas appelée automatiquement par le .NET Framework lorsque l'utilisateur clique sur le bouton de fermeture du formulaire d'une boîte de dialogue ou définit la valeur de la propriété DialogResult. En revanche, le formulaire est masqué et peut être affiché à nouveau sans créer une nouvelle instance de la boîte de dialogue. Dans la mesure où un formulaire affiché comme une boîte de dialogue n'est pas fermé, vous devez appeler sa méthode Dispose lorsqu'il n'est plus nécessaire à l'application.
    Avec la méthode Show() ce n'est pas nécessaire puisqu'il faut appeler la méthode Close() pour le fermer et implicitement le Dispose() donc.

  5. #5
    Membre émérite
    Profil pro
    Mangeur de gauffre
    Inscrit en
    Octobre 2007
    Messages
    4 413
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations professionnelles :
    Activité : Mangeur de gauffre

    Informations forums :
    Inscription : Octobre 2007
    Messages : 4 413
    Points : 2 498
    Points
    2 498
    Par défaut
    Oui !

    J'avais capté

    Merci aussi StormimOn

  6. #6
    Membre émérite
    Profil pro
    Mangeur de gauffre
    Inscrit en
    Octobre 2007
    Messages
    4 413
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations professionnelles :
    Activité : Mangeur de gauffre

    Informations forums :
    Inscription : Octobre 2007
    Messages : 4 413
    Points : 2 498
    Points
    2 498
    Par défaut Question subsidiaire !
    Connaissant bien la nuance entre .Close et .Dispose, une autre question se pose

    Dans une form Form1
    Dans une fonction J'ouvre une fenetre de dialogue non modale Form2 et lui passe une datatable dans le constructeur

    A tout moment dans Form1 je peux repasser par la fonction d'ouverture pour envoyer une autre datatable

    A part passer par des flags public comment savoir proprement que la form2 est déja ouverte pour eviter d'en ouvrir une autre ou la fermer si nécessaire !

  7. #7
    Membre confirmé
    Profil pro
    Inscrit en
    Janvier 2007
    Messages
    547
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2007
    Messages : 547
    Points : 627
    Points
    627
    Par défaut
    Salut,

    a part un test sur un flag, je ne vois pas beaucoup de methodes autres. Ceci dit c'est simple mais ca fera le job, donc pourquoi s'en priver. =p

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    Form2 frm2;
     
    //...
     
    if (!flag)
    {
        flag = true;
        frm2 = new Form2();
        frm2.Closed +=
            delegate
            {
                flag = false;
            };
        frm2.Show();
    }

  8. #8
    Membre émérite
    Profil pro
    Mangeur de gauffre
    Inscrit en
    Octobre 2007
    Messages
    4 413
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations professionnelles :
    Activité : Mangeur de gauffre

    Informations forums :
    Inscription : Octobre 2007
    Messages : 4 413
    Points : 2 498
    Points
    2 498
    Par défaut
    Merci SirJulio

    Ca me parrait effectivement le plus simple

    Mais encore un détail :
    Si je fais comme ca :
    A un moment je peux vouloir afficher la meme form2 mais avec une nouvelle datatable de Form1 que je passe par le constructeur

    Dois-je refermer Form2 depuis Form1 : si oui comment ?
    Ou dois-je faire autrement ?

    Désolé de ces questions sans doute triviale je dois encore consolider ma connaissance et mon expérience sur ce sujet

    Merci

    Certains me conseillent d'utiliser un Singleton : mais la je suis encore plus dans le brouillard !

  9. #9
    Membre confirmé
    Profil pro
    Inscrit en
    Janvier 2007
    Messages
    547
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2007
    Messages : 547
    Points : 627
    Points
    627
    Par défaut
    Pas de problemes, pour les questions, on a tous appris un jour. =)

    Si tu peux etre amené à fermer Form2 depuis la premiere, garde une reference (un champ) dans ta form1, et si tu dois instancier une nouvelle form2 appelle simplement .Close() avant.

    Apres singleton ou flag, ici le probleme du singleton, c'est que, dans son design standard, tu n'es pas sensé pouvoir la durée de vie de ce dernier (aka static), et de plus, Form2 n'existe que sur la requete et les parametres transmit par Form1. Bref, AMHA, le singleton n'est pas vraiment adapté ici, un bon vieux flag fera tres bien l'affaire, et sera, bien plus souple.

  10. #10
    Membre extrêmement actif Avatar de fally
    Homme Profil pro
    Développeur .Net / BI
    Inscrit en
    Novembre 2007
    Messages
    966
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Bénin

    Informations professionnelles :
    Activité : Développeur .Net / BI

    Informations forums :
    Inscription : Novembre 2007
    Messages : 966
    Points : 1 173
    Points
    1 173
    Par défaut
    Inspire-toi de ceci

  11. #11
    Membre éclairé
    Inscrit en
    Octobre 2006
    Messages
    587
    Détails du profil
    Informations personnelles :
    Âge : 37

    Informations forums :
    Inscription : Octobre 2006
    Messages : 587
    Points : 706
    Points
    706
    Par défaut
    Citation Envoyé par StormimOn Voir le message
    Pour information, chose que j'ai apprise récemment, lorsque que l'on affiche un formulaire avec la méthode ShowDialog(), il faut appeler la méthode Dispose() pour libérer proprement les ressources.
    Moi non plus je savais pas ça merci pour l'info.

  12. #12
    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 harz62 Voir le message
    Moi non plus je savais pas ça merci pour l'info.
    Dans ce cas, le mot-clé using est particulièrement utile :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    using (MaForm f = new MaForm())
    {
      DialogResult d  = f.ShowDialog();
      // ...
    }

  13. #13
    Membre éclairé
    Inscrit en
    Octobre 2006
    Messages
    587
    Détails du profil
    Informations personnelles :
    Âge : 37

    Informations forums :
    Inscription : Octobre 2006
    Messages : 587
    Points : 706
    Points
    706
    Par défaut
    Je fesais ça mais après je me suis dit que Dispose devait être appelée automatiquement...

  14. #14
    Membre émérite
    Profil pro
    Mangeur de gauffre
    Inscrit en
    Octobre 2007
    Messages
    4 413
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations professionnelles :
    Activité : Mangeur de gauffre

    Informations forums :
    Inscription : Octobre 2007
    Messages : 4 413
    Points : 2 498
    Points
    2 498
    Par défaut
    Je te suis pas ...

    Précisément le using gere le dispose automatiquement
    Donc pourquoi ne pas faire ainsi ?

  15. #15
    Membre éclairé
    Inscrit en
    Octobre 2006
    Messages
    587
    Détails du profil
    Informations personnelles :
    Âge : 37

    Informations forums :
    Inscription : Octobre 2006
    Messages : 587
    Points : 706
    Points
    706
    Par défaut
    Après j'avais arrêté de l'utiliser c'est pour ça que j'ai écrit ça.

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Réponses: 6
    Dernier message: 01/09/2006, 18h04
  2. [Form close] Impossible de fermer une form
    Par valoji dans le forum Bases de données
    Réponses: 4
    Dernier message: 17/03/2006, 15h12
  3. L'usage du CPU atteint 100% pour une Form
    Par Ben_Le_Cool dans le forum Composants VCL
    Réponses: 14
    Dernier message: 21/09/2005, 11h52
  4. [.NET] Pourquoi redéfinir la méthode dispose() d'une forme?
    Par Polyptyx dans le forum Général Dotnet
    Réponses: 3
    Dernier message: 07/09/2004, 12h10
  5. [VB6] Valeur de retour pour une Form
    Par preverse dans le forum VB 6 et antérieur
    Réponses: 3
    Dernier message: 17/08/2004, 17h16

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