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

Framework .NET Discussion :

[VS.net 2005] Destruction d'un objet


Sujet :

Framework .NET

  1. #1
    Membre éclairé
    Inscrit en
    Avril 2003
    Messages
    298
    Détails du profil
    Informations forums :
    Inscription : Avril 2003
    Messages : 298
    Par défaut [VS.net 2005] Destruction d'un objet
    Bonjour à tous,

    Je développe une classe que mon application va instancier assez souvent.
    Dans le new de cette classe, je passe en paramètre une référence à l'objet connection SQL.
    L'opération du new est de vérifier que l'ID fourni existe bien au niveau base de données et de charger les informations attachées.
    Dans le cas ou l'ID n'existe pas, le new lance une exception.
    Je récupère bien mon exception au niveau de mon application.

    Ma question est de savoir comment demander à l'objet de s'auto-détruire si l'ID n'est pas valable.
    En effet, lancer une exception ne détruit pas l'objet.

    Est-ce automatiquement la responsabilité de mon application de détruire l'objet si elle reçoit l'exceptionou existe-t-il une commande permettant, dans le new, de détruire l'objet lui-même.
    Je suis d'accord que c'est un peu comme de couper la branche sur laquelle on est assis mais dans mon cas, çà m'aiderait.

    Merci d'avance pour toute info.

    PS: Pour chaque objet que je crée, je transmet une référence à l'objet de connection SQL. Est-ce la meilleure approche ou serait-il préférable que chaque objet se reconnecte lui-même à ma DB? Sachant que je vais en instancier pas mal.

  2. #2
    Membre Expert
    Avatar de Piotrek
    Homme Profil pro
    Développeur .NET
    Inscrit en
    Mars 2004
    Messages
    869
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Ain (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur .NET

    Informations forums :
    Inscription : Mars 2004
    Messages : 869
    Par défaut
    Salut

    Ta classe ne fait que verifier l'existance d'un ID? dans ce cas je pencherai juste pour une fonction ailleurs, plus de question d'instanciation donc

    Pour ce qui est de la connection, cela depend. En .Net il est generalement deconseille de reutiliser une connection ouverte. Le systeme du pooling de .Net se charge de mettre en cache les connections a la base de donnees. Il est donc conseille d'ouvrir la connection le plus tard possible et de la refermer le plus tot possible.

    Autre remarque au cas ou:
    Il ne faut utiliser les exceptions que lorsqu'il sagit d'une anomalie de fonctionnement de l'application (dans ton cas la logique serait: il doit absolument toujours y avoir un ID) et non pas pour effectuer un simple test.

  3. #3
    Rédacteur
    Avatar de SaumonAgile
    Homme Profil pro
    Team leader
    Inscrit en
    Avril 2007
    Messages
    4 028
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Moselle (Lorraine)

    Informations professionnelles :
    Activité : Team leader
    Secteur : Conseil

    Informations forums :
    Inscription : Avril 2007
    Messages : 4 028
    Par défaut
    Citation Envoyé par Piotrek Voir le message
    Ta classe ne fait que verifier l'existance d'un ID? dans ce cas je pencherai juste pour une fonction ailleurs, plus de question d'instanciation donc
    +1
    Pourquoi ne pas faire une méthode statique ?
    Citation Envoyé par Piotrek Voir le message
    Pour ce qui est de la connection, cela depend. En .Net il est generalement deconseille de reutiliser une connection ouverte. Le systeme du pooling de .Net se charge de mettre en cache les connections a la base de donnees. Il est donc conseille d'ouvrir la connection le plus tard possible et de la refermer le plus tot possible.
    Ce qui, pour clarifier les choses, signifie que chaque objet gère sa propre connexion à la base. En interne le framework fait sa cuisine, il n'ouvre et ne ferme pas forcément les connexions lors de l'appel de Open et Close sur une IDbConnection. Mais pour toi cela est transparent. Donc au final, utilise une nouvelle connexion pour chaque objet et laisse le framework faire le boulot.
    Citation Envoyé par Piotrek Voir le message
    Autre remarque au cas ou:
    Il ne faut utiliser les exceptions que lorsqu'il sagit d'une anomalie de fonctionnement de l'application (dans ton cas la logique serait: il doit absolument toujours y avoir un ID) et non pas pour effectuer un simple test.
    +1 aussi.
    Besoin d'un MessageBox amélioré ? InformationBox pour .NET 1.1, 2.0, 3.0, 3.5, 4.0 sous license Apache 2.0.

    Bonnes pratiques pour les accès aux données
    Débogage efficace en .NET
    LINQ to Objects : l'envers du décor

    Mon profil LinkedIn - MCT - MCPD WinForms - MCTS Applications Distribuées - MCTS WCF - MCTS WCF 4.0 - MCTS SQL Server 2008, Database Development - Mon blog - Twitter

  4. #4
    Membre éclairé
    Inscrit en
    Avril 2003
    Messages
    298
    Détails du profil
    Informations forums :
    Inscription : Avril 2003
    Messages : 298
    Par défaut
    Citation:
    Envoyé par Piotrek
    Ta classe ne fait que verifier l'existance d'un ID? dans ce cas je pencherai juste pour une fonction ailleurs, plus de question d'instanciation donc

    +1
    Pourquoi ne pas faire une méthode statique ?
    Au new, ma classe vérifie l'ID mais elle ne fait pas que çà. Elle va aussi disposer de méthodes de calcul, ...
    Donc la classe reste dans mon cas la solution.

    Citation:
    Envoyé par Piotrek
    Autre remarque au cas ou:
    Il ne faut utiliser les exceptions que lorsqu'il sagit d'une anomalie de fonctionnement de l'application (dans ton cas la logique serait: il doit absolument toujours y avoir un ID) et non pas pour effectuer un simple test.
    Lorsque j'instancie ma classe, je lui passe l'ID de l'élément.
    - Première vérification, l'ID existe? Non, alors j'envoie une exception et exit le new (l'objet n'est donc pas créé)
    - Deuxième vérification, structure de l'ID (8 caractères maxi)
    Non, alors j'envoie une exception et exit le new (l'objet n'est donc pas créé)
    - Ultime vérification, l'ID existe dans la base de données?
    Non, alors j'envoie une exception et exit le new (l'objet n'est donc pas créé)

    J'utilise les exception pour transmettre la nature de l'erreur à la form qui instancie la objet.
    Y a-t-il une autre manière de faire? Sachant que je n'ai pas développé de classe spécifique pour mes exceptions(pour le moment)



    Citation:
    Envoyé par Piotrek
    Pour ce qui est de la connection, cela depend. En .Net il est generalement deconseille de reutiliser une connection ouverte. Le systeme du pooling de .Net se charge de mettre en cache les connections a la base de donnees. Il est donc conseille d'ouvrir la connection le plus tard possible et de la refermer le plus tot possible.
    Actuellement, j'ouvre la connexion au démarrage de l'appli et la passe en référence à chaque classe qui en a besoin.

    Tu penses que chaque objet devrait être responsable pour recréer une connection SQL? Si j'ai 2000 dossiers à instancier, j'aurai 2000 connection?
    Ces un débat que je tourne et retourne dans ma tête depuis quelques jours et j'aimerais connaître votre manière de faire. Un exemple?

    Merci pour toutes vos piste que je vais essayer de mettre en place.

  5. #5
    Rédacteur
    Avatar de SaumonAgile
    Homme Profil pro
    Team leader
    Inscrit en
    Avril 2007
    Messages
    4 028
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Moselle (Lorraine)

    Informations professionnelles :
    Activité : Team leader
    Secteur : Conseil

    Informations forums :
    Inscription : Avril 2007
    Messages : 4 028
    Par défaut
    Citation Envoyé par WriteLN Voir le message
    Tu penses que chaque objet devrait être responsable pour recréer une connection SQL? Si j'ai 2000 dossiers à instancier, j'aurai 2000 connection?
    Ces un débat que je tourne et retourne dans ma tête depuis quelques jours et j'aimerais connaître votre manière de faire. Un exemple?
    Si tu relis ma réponse précédente, tu auras la réponse à ta question. Mais je vais quand même le redire. Le framework gère les connexions en interne, ce n'est pas parce que tu crées 2000 objets DbConnection que tu vas ouvrir 2000 connexions à la base. Le framework gère un pool de connexions.
    Besoin d'un MessageBox amélioré ? InformationBox pour .NET 1.1, 2.0, 3.0, 3.5, 4.0 sous license Apache 2.0.

    Bonnes pratiques pour les accès aux données
    Débogage efficace en .NET
    LINQ to Objects : l'envers du décor

    Mon profil LinkedIn - MCT - MCPD WinForms - MCTS Applications Distribuées - MCTS WCF - MCTS WCF 4.0 - MCTS SQL Server 2008, Database Development - Mon blog - Twitter

  6. #6
    Membre Expert
    Avatar de Piotrek
    Homme Profil pro
    Développeur .NET
    Inscrit en
    Mars 2004
    Messages
    869
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Ain (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur .NET

    Informations forums :
    Inscription : Mars 2004
    Messages : 869
    Par défaut
    En fait l'objet ne s'auto detruit pas.

    C'est a l'objet qui a cree ton verificateur qu'incombe la responsabilite de le detruire. C'est pour cela que Finally existe. L'autodestruction n'existe pas

    Y a-t-il une autre manière de faire? Sachant que je n'ai pas développé de classe spécifique pour mes exceptions(pour le moment)
    A part si tu fais une application pour verifier la validite de donnees deja presentes en base (ce que tu fais apparement), dans les autres cas les d'infos concernant la validite des donnees en base peuvent etre gerees differment:
    - Si l'id unique existe en base et que tu tente d'inserer une donnees: tu ne fais pas le test de savoir s'il existe mais tu intercepte l'exception specifique d'ado.net qui te signale ce probleme apres avoir tente d'insere la donnee
    - Si une donnee doit comporter 8 caracteres, tu fais ton possible pour qu'en amont dans l'IMH (textbox de 8 char max) ou au niveau de l'objet, tout est fait pour que cela soit 8 caracteres. Si tu mets ces garde fous

    Donc comme apparement tu fais des verifications uniquement, je pense que tu fais bien.

    Actuellement, j'ouvre la connexion au démarrage de l'appli et la passe en référence à chaque classe qui en a besoin.
    Ca, ca marchait tres bien sous VB6. Mais ADO.Net a change la donne. Il existe un systeme de cache qui garde les connections a la base de donnees. Le but du jeux est d'avoir une seule connection active, dans ton code tu peux ouvrir et refermer une SqlConnection de partout, en fait ca sera la meme (a la condition que la connection string soit identique et qu'elle ait le temps de se referemer). A mon avis le code est plus sur et une partie de la mechanique d'une SqlConnection ne mobilise pas des ressources en permanence.

    Tu penses que chaque objet devrait être responsable pour recréer une connection SQL? Si j'ai 2000 dossiers à instancier, j'aurai 2000 connection?
    Ces un débat que je tourne et retourne dans ma tête depuis quelques jours et j'aimerais connaître votre manière de faire.
    Tes 2000 dossiers tu peux les charger dans une collection en une seule requete/connection, il faudrait en dire plus sur ce que tu fais

  7. #7
    Membre éclairé
    Inscrit en
    Avril 2003
    Messages
    298
    Détails du profil
    Informations forums :
    Inscription : Avril 2003
    Messages : 298
    Par défaut
    Donc si mon objet, au NEW, renvoie une exception, l'objet responsable de la création fait le catch et détruit celui-ci.

    Pour la connection à SQL, je vais devoir repenser mon application alors.
    Malgré qu'elle fonctionne très bien sur cet aspect la mais je préfère être sûr.

    Enfin, pour le concept, c'est une application qui, entre autres..., ouvre un fichier XML, lis les ID des items les uns après les autres, instancie pour chaque items la classe d'affichage graphique de 'objet' qui elle instancie la classe métier pour les données.
    Ces objets sont affichés à l'écran et l'utilisateur peut interagir avec eux (doubleclick, click, drag, ...)

    Merci encore pour tout. on peut dire que c'est résolu. J'ai saisi l'idée
    La prochaine fois, je ferai des études de masseur C moins compliqué

  8. #8
    Membre Expert
    Profil pro
    Inscrit en
    Juillet 2006
    Messages
    1 103
    Détails du profil
    Informations personnelles :
    Âge : 47
    Localisation : France, Meurthe et Moselle (Lorraine)

    Informations forums :
    Inscription : Juillet 2006
    Messages : 1 103
    Par défaut
    jvais mettre mon grain de sel...

    Si je me souviens bien, on est bien en .NET là... et je me souviens toujours bien ca signifie univers MANAGE et si je me souviens toujours bien... dans un univers managé... ON NE DETRUIT PAS UN OBJET car il n'y a pas de destructeur. Le mieux que tu puisse faire c'est demander au GC de faire le ménage dans ses collections... mais là aussi... ce n'est pas déterministe car il ne le fera pas forcément, s'il juge s'etre lancé ya trop de peu de temps à son gout...
    Quand a l'implantation de IDisposable... cela ne sert pour la libération déterministe des ressources systèmes hors environnement managées. Ce sera donc pratique si t"utilise des tonnes d'objets qui implantent eux même IDiposable, ou si tu alloue de la mémoire non managé,ou des ressources non managées comme des ressources DirectX si tu veux pas utiliser les extensions managées ou je ne sais quoi d'autre...

    Autre détail... Tu semble oublier un détail... 2000 instanciations de l'objet entrainant 2000 instanciations de la connexion SQL... LES INSTANCIATIONS NE SONT PÄS DES OPERATIONS GRATUITES surtout en environnement managées. Et oui, s'il veut déja libérer la mémoire, c'est qu'il veut pas consommer un max de mémoire... PAR CONSEQUENT une connexion unique est préférable surtout s'il ne passe pas son temps à la fermer.
    Meme si les connexions sont mises en cache... tout est question de timing, et de consommation mémoire. Pour peu que le timing soit pas convenable et au lieu de réutiliser la connexion, il va en reconstruire une... tu parle d'un intérêt.
    En revanche là où le cache est génial... c'est dans les ASP, oui là c'est parfait la page existe elle créer la connexion, se connecte bosse, ferme et se termine
    le mec reclic... pouf la connexion est réutilisée comme si de rien était en toute trransparence et on perd pas le temps de la connexion/authentification.... C'est surtout dans ce cas que le cache sert à quelque chose.

    Dans son exemple il instancie 2000 objets + 2000 objets SqlConnexions, même si en interne ils utilisent TOUS la meme connexion physique, ces objets existent tous quand meme, et consomme de la mémoire... pas forcément utile
    surtout si les 2000 tests doivent se faire quasiment tous en même temps... dans ce cas autant avoir un seul objet SqlConnexion... toute facon ce que vous avez dit est tout aussi valable sur la connexion réelle ou non à la base de données. A titre indicatif, à moins de faire Open toi meme on ne se connecte pas systematiquement, et chaque commande fait la vérification donc... tu peux direct faire une requete, si l'objet est pas ouvert il le sera, et éventuellement fermé si tropde temps passe entre temps (et les ressources systemes allouées libérées à ce moment au passage) je le sais je procède comme ca et à part un accroissement considérable de la mémoire j'ai pas percut de différence entre 1 objet unique (voir 2) et 15000 pour la meme chose.

  9. #9
    Membre éclairé
    Inscrit en
    Avril 2003
    Messages
    298
    Détails du profil
    Informations forums :
    Inscription : Avril 2003
    Messages : 298
    Par défaut
    Merci beaucoup pour tes précisions.

    En fait chaque objet 'Dossier' doit aller, au new, vérifier dans la DB si l'ID tranmis existe, si oui, je récupère les data voulues dans les membres de ma classe, si non, je lance une exception.

    Etant donné qu'à l'écran je dois afficher pas mal de dossiers, chacun d'eux va aller chercher sa petite info. Le tout prenant pas mal de temps, l'écran freeze un court instant et c'est cela que je voulais éviter par l'utilisation de threads.

    Chaque dossier récupère actuellement une référence à la classe SQLconnection au new.
    Ils utilisent donc tous la même ^^
    L'idée serait alors de faire un nouveau SQLconnection et de se reconnecter dans chaque objet? Par défaut il reprendra celle qui existe si il y en a une mais avec l'avantage de travailler dans un contexte différent. Cela me permettrait d'exécuter plusieurs requête "en même temps" sans mon erreur de datareader.

    Je m'en vais tester ca tout de suite...

  10. #10
    Rédacteur
    Avatar de SaumonAgile
    Homme Profil pro
    Team leader
    Inscrit en
    Avril 2007
    Messages
    4 028
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Moselle (Lorraine)

    Informations professionnelles :
    Activité : Team leader
    Secteur : Conseil

    Informations forums :
    Inscription : Avril 2007
    Messages : 4 028
    Par défaut
    Dans ce cas là, pourquoi ne pas faire une méthode qui va effectuer ces actions pour une liste d'ID donnée. J'ai l'impression que le problème de connexion est un faux problème, tu devrais minimiser les requêtes plutot qu'essayer de minimiser les connexions.
    Je vois bien trop souvent des concepts de ce genre :
    Constat : J'ai une méthode M qui renvoie les données d'un client.
    Problème : J'ai besoin de récupérer les infos de 1000 clients
    Solution sale : J'appelle 1000 fois la méthode M
    Solution efficace : Modifier la méthode M pour qu'elle prenne en paramètre une liste de 1000 ID client à charger et qui traite les ID par bloc de taille prédéfinie. "Qui peut le plus, peut le moins".
    Besoin d'un MessageBox amélioré ? InformationBox pour .NET 1.1, 2.0, 3.0, 3.5, 4.0 sous license Apache 2.0.

    Bonnes pratiques pour les accès aux données
    Débogage efficace en .NET
    LINQ to Objects : l'envers du décor

    Mon profil LinkedIn - MCT - MCPD WinForms - MCTS Applications Distribuées - MCTS WCF - MCTS WCF 4.0 - MCTS SQL Server 2008, Database Development - Mon blog - Twitter

  11. #11
    Membre éclairé
    Inscrit en
    Avril 2003
    Messages
    298
    Détails du profil
    Informations forums :
    Inscription : Avril 2003
    Messages : 298
    Par défaut
    Effectivement çà semble plus efficace.
    Mon idée était de donner à chaque objet la responsabilité d'aller lui même chercher ses infos dans la base afin d'encapsuler les méthodes liées à l'objet.

    Dans ton ordre d'idée, je devrais plutôt créer une classe qui va chercher les données necessaires à mes 1000 objets et qui les leur transmet ?

    Je m'excuse d'être aussi insistant mais j'aimerais développer cette appli qui risque de grandir très vite de manière propre dés le départ pour éviter les retours en arrière dans le futur et du travail de correction.

    En tout cas vos réponses me permettent d'avancer.

  12. #12
    Rédacteur
    Avatar de SaumonAgile
    Homme Profil pro
    Team leader
    Inscrit en
    Avril 2007
    Messages
    4 028
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Moselle (Lorraine)

    Informations professionnelles :
    Activité : Team leader
    Secteur : Conseil

    Informations forums :
    Inscription : Avril 2007
    Messages : 4 028
    Par défaut
    Tes objets Dossier sont créés par une méthode définie je suppose. Cette méthode va donc garder les ID des Dossier sous la main et une fois que c'est nécessaire (je ne connais pas tes conditions), elle va appeler le chargement des X 'Dossier' et les mettre à jour en un seul passage, cad tu récupères toutes les données en une fois et tu mets à jour tous les 'Dossier' pour par exemple supprimer ceux dont l'ID n'a pas été trouvé.
    Besoin d'un MessageBox amélioré ? InformationBox pour .NET 1.1, 2.0, 3.0, 3.5, 4.0 sous license Apache 2.0.

    Bonnes pratiques pour les accès aux données
    Débogage efficace en .NET
    LINQ to Objects : l'envers du décor

    Mon profil LinkedIn - MCT - MCPD WinForms - MCTS Applications Distribuées - MCTS WCF - MCTS WCF 4.0 - MCTS SQL Server 2008, Database Development - Mon blog - Twitter

  13. #13
    Membre éclairé
    Inscrit en
    Avril 2003
    Messages
    298
    Détails du profil
    Informations forums :
    Inscription : Avril 2003
    Messages : 298
    Par défaut
    OK je vais tenter cette solution qui me semble interessante.
    En fait c'est surtout la conception qu'il faut que je revois.

    Merci encore pour votre aide.
    Bon coding

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

Discussions similaires

  1. [VS.net 2005] Conception orientée objet
    Par WriteLN dans le forum VB.NET
    Réponses: 16
    Dernier message: 24/09/2007, 10h26
  2. [VS.net 2005] Question philosophique sur les objets
    Par WriteLN dans le forum Framework .NET
    Réponses: 8
    Dernier message: 23/08/2007, 10h34
  3. [VB.NET 2005] Propriété opacity sur un objet
    Par ricil78 dans le forum Windows Forms
    Réponses: 3
    Dernier message: 24/04/2007, 11h11
  4. [CR VS 2005] Source de données Objet .net
    Par Cereal123 dans le forum SDK
    Réponses: 4
    Dernier message: 08/03/2007, 10h46
  5. [VB.net 2005] Modelisation objet
    Par WriteLN dans le forum Windows Forms
    Réponses: 3
    Dernier message: 21/02/2007, 13h07

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