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 :

Quand utiliser la methode Dispose() ?


Sujet :

C#

  1. #1
    Membre à l'essai
    Homme Profil pro
    programmeur
    Inscrit en
    Juillet 2014
    Messages
    31
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Algérie

    Informations professionnelles :
    Activité : programmeur

    Informations forums :
    Inscription : Juillet 2014
    Messages : 31
    Points : 24
    Points
    24
    Par défaut Quand utiliser la methode Dispose() ?
    Bonjour,

    La question est son titre, je voudrai savoir quand dois je utiliser cette méthode pour libérer une ressource. est ce que c'est obligatoire, ou est ce que le garbage collector peut s'en charger tout seul?

    je voudrai savoir aussi quand est ce qu'il s'agit d'un objet ( quand il est instancié avec "new", ou alors meme sans?).

    comme je suis un débutant essayez de faire simple svp.

    Merci

  2. #2
    Expert confirmé Avatar de DonQuiche
    Inscrit en
    Septembre 2010
    Messages
    2 741
    Détails du profil
    Informations forums :
    Inscription : Septembre 2010
    Messages : 2 741
    Points : 5 485
    Points
    5 485
    Par défaut
    Bonjour.

    Imagine que ton programme ouvre un fichier. Tant que Dispose n'a pas été appelé celui-ci est verrouillé et inaccessible aux autres applications. Bien sûr tu pourrais attendre que le ramasse-miettes appelle Dispose (ou plus précisément dans ce cas le finaliseur). Mais en tant qu'utilisateur tu ne préfères pas qu'un programme libère ce fichier dès le moment où il n'en a plus besoin ? D'autant que le ramasse-miettes (GC) pourrait ne jamais être appelé si ton appli reste inactive.

    On a aussi le cas typique du système qui lit de nombreuses images et finit par bouffer la mémoire et ralentir tout le système : les images sont représentées par des objets non-dotnet dans un autre processus donc dotnet présume que le problème ne vient pas de lui et ne lance pas son GC.


    Enfin note qu'en général on n'appelle pas Dispose directement mais plutôt via un bloc "using". Celui-ci appelle tout simplement Dispose à la fin, et met en place un bloc finally pour le faire même si une exception a été rencontrée.

    Code c# : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    using (var file = File.Open(...))
    {
        // Faire quelque chose avec file
    }

  3. #3
    Membre à l'essai
    Homme Profil pro
    programmeur
    Inscrit en
    Juillet 2014
    Messages
    31
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Algérie

    Informations professionnelles :
    Activité : programmeur

    Informations forums :
    Inscription : Juillet 2014
    Messages : 31
    Points : 24
    Points
    24
    Par défaut
    Bonjour,

    Merci DonQuiche,

    Au sujet de "using", j'ai une difficulté a l'utiliser, quand il s'agit d'une référence d'objet globale, en utilisant using je ne vois pas comment cerner la portée d'utilisation de mon objet, sachant que j'utilise ce dernier dans plusieurs methodes ?

  4. #4
    Membre actif
    Homme Profil pro
    Developpeur
    Inscrit en
    Février 2013
    Messages
    180
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 31
    Localisation : France, Ille et Vilaine (Bretagne)

    Informations professionnelles :
    Activité : Developpeur

    Informations forums :
    Inscription : Février 2013
    Messages : 180
    Points : 271
    Points
    271
    Par défaut
    non justement le using est la pour limité la porté au maximum
    par exemple accéder à une base de donnée, si on utilise pas de pool de connexion
    si faut ouvrir la connexion récupérer les informations puis refermer aussitôt.

    Quand ton code fait un appel vers l'extérieur pense automatiquement "est-ce que je peux utiliser le using"
    ça sera une bonne sécurité pour ton programme.

    sinon avec des objets passer de méthode en méthode on peut se retrouvé avec des fichier ouvert et jamais refermé.

    voici quelque exemple
    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
    16
    17
    18
    19
    20
    21
     
    //BDD
    using (IDbConnection cnx = SQLAcces.SeConnecter())
    {
        IDbCommand cmd = SQLAcces.CreerCommand(cnx, SELECT_TESTCONNECTIONTIERS, CommandType.Text);
        retour = SQLAcces.Count(cmd.ExecuteReader());
    }
     
    //lecture de fichier
    using (FileStream fs = new FileStream(_pathFile, FileMode.Open, FileAccess.Read, FileShare.Read))
    {
        objetDeserialisee = (T)((IFormatter)_formatter).Deserialize(fs);
        return objetDeserialisee;
    }
     
    //Ecriture
    using (System.IO.StreamWriter sw = new System.IO.StreamWriter(strFullPathToMyFile, true))
    {
        sw.WriteLine(DateTime.Now.ToLongDateString() + "_" + DateTime.Now.ToLongTimeString() + " - " + chaine);
        sw.Flush();
    }

  5. #5
    Membre à l'essai
    Homme Profil pro
    programmeur
    Inscrit en
    Juillet 2014
    Messages
    31
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Algérie

    Informations professionnelles :
    Activité : programmeur

    Informations forums :
    Inscription : Juillet 2014
    Messages : 31
    Points : 24
    Points
    24
    Par défaut
    Bonjour,

    Merci ranzoken,


    Citation Envoyé par ranzoken Voir le message

    Quand ton code fait un appel vers l'extérieur pense automatiquement "est-ce que je peux utiliser le using"
    ça sera une bonne sécurité pour ton programme.
    Est ce que ça veut dire que je dois éviter les variables globales des objet que j'instancie ?
    J'ai pris comme habitude d'utiliser beaucoup les variables globales, ça m'a parus plus lisible et plus facile !?

  6. #6
    Expert confirmé
    Avatar de popo
    Homme Profil pro
    Analyste programmeur Delphi / C#
    Inscrit en
    Mars 2005
    Messages
    2 674
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Analyste programmeur Delphi / C#
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mars 2005
    Messages : 2 674
    Points : 5 259
    Points
    5 259
    Par défaut
    Citation Envoyé par Ryadassakr Voir le message
    Bonjour,

    Merci ranzoken,

    Est ce que ça veut dire que je dois éviter les variables globales des objet que j'instancie ?
    J'ai pris comme habitude d'utiliser beaucoup les variables globales, ça m'a parus plus lisible et plus facile !?
    Tout dépend de ce que tu entends pas "globales".
    J'ai pus constater que, le plus souvent, lorsque les gens parlent de variables globales en C, ils parlent de variables stockée à l'intérieur d'une seule et même classe (genre un BackgroundWorker dans une form ou encore un XMlSerializer dans un helper pour sérialiser un objet particulier).

    Dans ce cas là, tu peux faire en sorte que ta classes "conteneur" implémente IDisposable pour faire le Dispose de tous ces Objets au même moment. Cet Objet conteneur pourra être encadré par un "using"

  7. #7
    Membre actif
    Homme Profil pro
    Developpeur
    Inscrit en
    Février 2013
    Messages
    180
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 31
    Localisation : France, Ille et Vilaine (Bretagne)

    Informations professionnelles :
    Activité : Developpeur

    Informations forums :
    Inscription : Février 2013
    Messages : 180
    Points : 271
    Points
    271
    Par défaut
    Citation Envoyé par Ryadassakr Voir le message
    Est ce que ça veut dire que je dois éviter les variables globales des objet que j'instancie ?
    J'ai pris comme habitude d'utiliser beaucoup les variables globales, ça m'a parus plus lisible et plus facile !?
    Alors, je ne te dirais pas de les éviter, personnellement j'utilise le plus rarement possible les variables Global, après ça reste ma façon de faire.

    après rien ne t'oblige à utiliser le using, mais à mon sens pour certain objet celui ci est obligatoire.
    par exemple des que tu accède à des ressources partagées, les exemples que j'ai mis plus haut en font partis.

  8. #8
    Membre à l'essai
    Homme Profil pro
    programmeur
    Inscrit en
    Juillet 2014
    Messages
    31
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Algérie

    Informations professionnelles :
    Activité : programmeur

    Informations forums :
    Inscription : Juillet 2014
    Messages : 31
    Points : 24
    Points
    24
    Par défaut
    Bonjour,

    merci popo et ranzoken,

    J'aurai 2 questions encore à poser svp:

    1- est ce que popo peux me donner un exemple d'implémentation c# d'un "Dispose" pour une classe personnelle ?
    2- pourriez vous me dire ce qui ce passe quand il y a un crash ou une coupure de courant pour les objet dans le cas du "using" et sans?

  9. #9
    Expert confirmé Avatar de DonQuiche
    Inscrit en
    Septembre 2010
    Messages
    2 741
    Détails du profil
    Informations forums :
    Inscription : Septembre 2010
    Messages : 2 741
    Points : 5 485
    Points
    5 485
    Par défaut
    Citation Envoyé par Ryadassakr Voir le message
    2- pourriez vous me dire ce qui ce passe quand il y a un crash ou une coupure de courant pour les objet dans le cas du "using" et sans?
    Les using fonctionnent comme les blocs finally :
    * Ils sont presque toujours exécutés sauf en cas de fermeture d'urgence de l'application ou de l'hôte, ou en cas de coupure de courant ou défaillance matérielle. Ce qui peut survenir avant ou au milieu d'un bloc finally. Si tu dois résister à cela il faut stocker sur le disque de quoi récupérer d'une erreur, ou passer par des opérations atomiques sur les fichiers. C'est ce que font les bases de données, tu n'as pas de précaution à prendre pour ces dernières.

    * Une exception peut survenir dans le bloc finally et l'interrompre. Par exemple si une méthode est exécutée pour la première fois le JIT tentera de la compiler et s'il n'a pas assez de mémoire il lèvera une exception. Les zones "CER" permettent de réclamer une vérification de la profondeur de la pile et une pré-compilation avant le début du bloc try.

    * En revanche les blocs finally protègent contre ThreadAbortException : l'arrêt du thread est retardé jusqu'à ce que tous les blocs aient été exécutés. Il en va de même pour les tentatives normales de fermeture de l'application. J'ai un doute sur les threads d'arrière-plan mais je crois que les finally seront exécutés.

    * Avant de te soucier de faire un code capable de résister à une panne de courant, considère le fait que même avec de la mémoire ECC tu as quelques pourcents de risque par année d'avoir un octet corrompu parmi les données en mémoire. Les disques ont aussi des problèmes de ce genre. Pour détecter de façon fiable les problèmes il faut des mécanismes d'intégrité assez lourds. Et pour corriger de façon certaine il n'y a que la redondance sur plusieurs machines et plusieurs sites... Certains font tourner trois machines simultanément et comparent les résultats.

  10. #10
    Membre à l'essai
    Homme Profil pro
    programmeur
    Inscrit en
    Juillet 2014
    Messages
    31
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Algérie

    Informations professionnelles :
    Activité : programmeur

    Informations forums :
    Inscription : Juillet 2014
    Messages : 31
    Points : 24
    Points
    24
    Par défaut
    Bonjour,


    Merci DonQuiche,


    Avant de mettre fin à la discution, quelqu'un peut il me répondre à la question n°1, svp ?

Discussions similaires

  1. [debutant]Utiliser friend method
    Par Battosaiii dans le forum Débuter
    Réponses: 4
    Dernier message: 06/11/2005, 11h23
  2. [Language]utilisation de méthodes dans différentes classes
    Par The Wretched dans le forum Langage
    Réponses: 4
    Dernier message: 09/05/2005, 16h17
  3. Réponses: 10
    Dernier message: 08/02/2005, 10h52
  4. Écriture dans un DBgrid quand utilise un query comme dataset
    Par dcayou dans le forum Bases de données
    Réponses: 3
    Dernier message: 13/07/2004, 22h22
  5. [Procédure Stocké] Quand utiliser ?
    Par touhami dans le forum Bases de données
    Réponses: 2
    Dernier message: 18/03/2004, 09h09

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