Twitter iPhone pliant OnePlus 11 PS5 Disney+ Orange Livebox Windows 11

clause finally et classes IDisposable

5 réponses
Avatar
LeXave
Bonjour,

J'ai une classe qui utilise une connexion =E0 une base de donn=E9es ODBC.
Cette classe poss=E8de une variable membre de type OdbcDataReader.
Cette classe impl=E9mente IDisposable pour la lib=E9ration du reader. Ma
question est la suivante : je lis le reader dans un try/catch/finally.
Dans le finally, je fais un reader.close().

Etant donn=E9 que je ferme aussi le reader dans la m=E9thode Dispose() de
ma classe (qui impl=E9mente IDisposable), dois-je aussi le fermer dans
le finally (qui sera appel=E9 quoi qu'il arrive), y'a t'il un risque de
NullPointerException quelconque ?

Merci par avance

5 réponses

Avatar
Patrick Philippot
Bonjour,

LeXave wrote:
Etant donné que je ferme aussi le reader dans la méthode Dispose() de
ma classe (qui implémente IDisposable), dois-je aussi le fermer dans
le finally (qui sera appelé quoi qu'il arrive), y'a t'il un risque de
NullPointerException quelconque ?



A priori non puisqu'un Close n'est pas un abandon de référence. 2 Close
subséquents sur une même référence ne devraient pas avoir d'effet nocif; on
exéxcutera juste un peu de code inutilement pour constater que le DataReader
est déjà clos.

Mais pour être plus cohérent, pourquoi ne pas appeler Dispose au lieu de
Close?

--
Patrick Philippot - Microsoft MVP
MainSoft Consulting Services
www.mainsoft.fr
Avatar
LeXave
On 3 oct, 17:03, "Patrick Philippot"
wrote:

Mais pour être plus cohérent, pourquoi ne pas appeler Dispose au lieu de
Close?



Oui, c'est ce que je fais dans le finally (et pas un close(), je n'ai
pas relu mon message précédent, désolé), mais en fait je me pose
carrément la question de l'utilité du finally : si jamais une
exception se produit, j'affiche un message d'erreur et je rend la main
à l'appelant. Dés l'instant ou une référence à ma classe IDisposa ble
n'existera plus, le Dispose() sera appelé. Donc le finally est il
vraiment obligatoire, étant donné que le reader sera de toute façon
fermé à un moment ou à un autre ?
Avatar
Gilles TOURREAU
Le Wed, 03 Oct 2007 17:37:24 +0200, LeXave a écrit:

On 3 oct, 17:03, "Patrick Philippot"
wrote:

Mais pour être plus cohérent, pourquoi ne pas appeler Dispose au lieu de
Close?



Oui, c'est ce que je fais dans le finally (et pas un close(), je n'ai
pas relu mon message précédent, désolé), mais en fait je me pose
carrément la question de l'utilité du finally : si jamais une
exception se produit, j'affiche un message d'erreur et je rend la main
à l'appelant. Dés l'instant ou une référence à ma classe IDisposable
n'existera plus, le Dispose() sera appelé. Donc le finally est il
vraiment obligatoire, étant donné que le reader sera de toute façon
fermé à un moment ou à un autre ?




La méthode Dispose est normalement appelé par le GC, si elle n'est pas
appelée explicitement. On ne peut donc pas prédire quand la méthode
Dispose() sera appelée...
Préférez donc d'appelez cette méthode dans finally par mesure de sécurité
ou utilisez la clause "using()"...
Plus tôt vous appelerez votre Dispose(), plus tôt les ressources attachées
à la classe seront libérées...

Cordialement

--
Gilles TOURREAU


S.A.R.L. P.O.S
Le spécialiste en motoculture depuis + de 30 ans !
http://www.pos.fr
Avatar
Patrick Philippot
LeXave wrote:

Dés l'instant ou une référence à ma classe IDisposable
n'existera plus, le Dispose() sera appelé. Donc le finally est il
vraiment obligatoire, étant donné que le reader sera de toute façon
fermé à un moment ou à un autre ?



Ce n'est pas le finally qui est en cause mais ce que vous faites dedans. Si
vous ne faites qu'appeler le Close, cela fait effectivement double emploi.
Cependant, le finally peut aussi servir à d'autres opérations de nettoyage.

Par ailleurs, vous nous dites que le Datareader est un membre de la classe.
La référence existe donc toujours tant que l'instance de la classe est
vivante. le Close ne sera donc fait que lorsque l'instance sera détruite. La
méthode qui contient le try / catch / finally peut éventuellement être
appelée plusieurs fois pendant la durée de vie de l'instance de la classe
conteneur. Il peut donc être intéressant de faire un Close quand cette
méthode échoue de manière à repartir du bon pied pour une opération
subséquente et libérer des ressources qui nont plus lieu d'être.

--
Patrick Philippot - Microsoft MVP
MainSoft Consulting Services
www.mainsoft.fr
Avatar
Christophe Lephay
"LeXave" a écrit dans le message de news:

J'ai une classe qui utilise une connexion à une base de données ODBC.
Cette classe possède une variable membre de type OdbcDataReader.
Cette classe implémente IDisposable pour la libération du reader. Ma
question est la suivante : je lis le reader dans un try/catch/finally.
Dans le finally, je fais un reader.close().

Etant donné que je ferme aussi le reader dans la méthode Dispose() de
ma classe (qui implémente IDisposable), dois-je aussi le fermer dans
le finally (qui sera appelé quoi qu'il arrive), y'a t'il un risque de
NullPointerException quelconque ?



1- C'est à toi d'écrire la fonction dispose de manière à éviter de libérer
plusieurs fois les ressources non-managées ;
2- utilise une clause using de préférence à un try...catch (dans la mesure
du possible).