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

Dispose : quelles ressources sont concernées ?

11 réponses
Avatar
Johnny
Bonjour ou bonsoir,

Je crée une classe MaClasse implémentant l'interface IDisposable.
Vous trouverez (sans entrer dans le détail) l'allure de mon code à la fin de
mon message.
Je me pose quelques questions au sujet du contenu de la méthode public void
Dispose( bool disposing )

1) Ma classe contient quelques variables private de type string. Est-ce
qu'il y a un intéret à faire un this.maVariableString = null; ?

2) D'une manière générale, j'envisage de mettre à null tous les objets,
managés ou non, et d'appeller au préalable la methode .Dispose() si et
seulement si l'objet a été crée par la classe ( et bien entendu si l'objet à
"nullifier" propose la méthode Dispose() (*) ).

3) MaClasse travaille avec une base de données et possède une donnée private
de type IDbConnection. Cet objet de type IDbConnection est un argument d'un
constructeur; il est aussi accessible en lecture/écriture (get/set) via une
propriété. J'envisage donc, dans mon Dispose, de faire un simple
this.MonIdbConnection = null;. Je n'envisage rien d'autre, en particulier
aucun appel à un .Close() ou un .Dispose() car la connexion est partagée :
l'orsque mon objet de type MaClasse est créé, il existe déjà un autre objet
MaConnexion (de type IDbConenction, ou OleDbConnecttion ou...) et cet autre
objet "pointe" déjà une base et est "ouvert". Je passe donc MaConnexion au
constructeur de MaClasse, afin de profiter d'une connexion ouverte et donc
de faire l'économie d'une connexion supplémentaire... Est-ce là une bonne
pratique ? Je pose la question car j'ai lu, içi ou là dans quelques posts,
qu'il existerait un mécanisme de "pool de connexion" (**) ? Si ce mécanisme
est efficace et général, je pourrais alors passer plutôt par une chaine de
connexion, et créer une nouvelle connexion réellement propre à MaClasse,
puis fermer la conenxion dans le Dispose(), et par exemple ne pas supposer
ou vérifer que MaConnexion est ou non ouverte lorsque j'en ai besoin dans
MaClasse...

4) Accessoirement, je suppose qu'il y a un moyen (simple) de vérifier si un
objet implémente une interface (réflexion) ?

Merci à tous

Johnny

(*) Même chose pour le "Close()" si "Open()" réalisé dans la classe
(**) Avez-vous un (bon) lien à ce sujet ?

//---------------------------------------
//--------------------------------------- Portion de code
//---------------------------------------

public void Dispose()
{
this.Dispose( true );
GC.SuppressFinalize( this );
}

public void Dispose( bool disposing )
{
if( disposing )
{
// Suppression des objets managés
}
// Suppression des objets non managés
}

~MaClasse()
{
this.Dispose( false );
}

10 réponses

1 2
Avatar
Piotrek
"Johnny" wrote in message
news:4159c0e9$0$2232$
Bonjour ou bonsoir,

Je crée une classe MaClasse implémentant l'interface IDisposable.
Vous trouverez (sans entrer dans le détail) l'allure de mon code à la fin


de
mon message.
Je me pose quelques questions au sujet du contenu de la méthode public


void
Dispose( bool disposing )

1) Ma classe contient quelques variables private de type string. Est-ce
qu'il y a un intéret à faire un this.maVariableString = null; ?



Non pas besoin
Il y a quelques debats sur le net a ce propos (pas pour des strings je te
rassure) donc en regle generale: non pas besoin

2) D'une manière générale, j'envisage de mettre à null tous les objets,
managés ou non, et d'appeller au préalable la methode .Dispose() si et
seulement si l'objet a été crée par la classe ( et bien entendu si l'objet


à
"nullifier" propose la méthode Dispose() (*) ).



C'est legitime de penser a faire cela, mais le garbage collector se charge
de verifier l'arboresence des references:
Si ta classe n'est plus referencee nulle part, tous les objets uniquement
lies a ta classe seront eligibles au nettoyage
(il FAUT que tu lises les articles des liens que j'ai mis tt en bas)

3) MaClasse travaille avec une base de données et possède une donnée


private
de type IDbConnection. Cet objet de type IDbConnection est un argument


d'un
constructeur; il est aussi accessible en lecture/écriture (get/set) via


une
propriété. J'envisage donc, dans mon Dispose, de faire un simple
this.MonIdbConnection = null;. Je n'envisage rien d'autre, en particulier
aucun appel à un .Close() ou un .Dispose() car la connexion est partagée :
l'orsque mon objet de type MaClasse est créé, il existe déjà un autre


objet
MaConnexion (de type IDbConenction, ou OleDbConnecttion ou...) et cet


autre
objet "pointe" déjà une base et est "ouvert". Je passe donc MaConnexion au
constructeur de MaClasse, afin de profiter d'une connexion ouverte et donc
de faire l'économie d'une connexion supplémentaire... Est-ce là une bonne
pratique ? Je pose la question car j'ai lu, içi ou là dans quelques posts,
qu'il existerait un mécanisme de "pool de connexion" (**) ? Si ce


mécanisme
est efficace et général, je pourrais alors passer plutôt par une chaine de
connexion, et créer une nouvelle connexion réellement propre à MaClasse,
puis fermer la conenxion dans le Dispose(), et par exemple ne pas supposer
ou vérifer que MaConnexion est ou non ouverte lorsque j'en ai besoin dans
MaClasse...



Pas bonne idee: j'avais fait un gestionnaire malin de connections dans mon
programme. Je me suis retrouve bete quand j'ai fait quelques benchs: je ne
gagnais rien sinon de la complexite
Le pool marche tres tres bien.
Sauf que attention: son critere pour reutiliser une connection c'est
justement la connection string. Si elle differe ne serait-ce que d'un
espace, le pooling va creer une nouvelle connection.

Donc la regle que j'applique est celle qui est officiellement proposee:
Ouvrir la connection le plus tard possible, la referemer le plus tot
possible

En utilisant le pooling, tu remarqueras que ca simplifie pas mal ton
probleme
.
4) Accessoirement, je suppose qu'il y a un moyen (simple) de vérifier si


un
objet implémente une interface (réflexion) ?



heu... cela peut-etre:
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/cpref/html/frlrfsystemtypeclassfindinterfacestopic.asp



qq articles interessants garbage collector:
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/cpguide/html/cpconprogrammingessentialsforgarbagecollection.asp
http://msdn.microsoft.com/msdnmag/issues/1100/GCI/
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dndotnet/html/dotnetgcbasics.asp
Avatar
Zazar
Bonjour,

> 1) Ma classe contient quelques variables private de type string. Est-ce
> qu'il y a un intéret à faire un this.maVariableString = null; ?

Non pas besoin
Il y a quelques debats sur le net a ce propos (pas pour des strings je te
rassure) donc en regle generale: non pas besoin



Je suis d'accord.


> 2) D'une manière générale, j'envisage de mettre à null tous les objets,
> managés ou non, et d'appeller au préalable la methode .Dispose() si et
> seulement si l'objet a été crée par la classe ( et bien entendu si


l'objet
à
> "nullifier" propose la méthode Dispose() (*) ).

C'est legitime de penser a faire cela, mais le garbage collector se charge
de verifier l'arboresence des references:
Si ta classe n'est plus referencee nulle part, tous les objets uniquement
lies a ta classe seront eligibles au nettoyage
(il FAUT que tu lises les articles des liens que j'ai mis tt en bas)


Appeler la méthode Dispose des objets utilisés en interne est tout à fait
légitime : l'appelant a demandé une libération explicite et immédiate des
ressources, cette libération doit être faîte.
Par contre mettre à null, les variables dans la méthode Dispose n'a pas
d'intérêt. Cela aurait un intérêt (du point de vue performances) de le faire
lors de l'utilisation de votre objet (avant l'appel à Dispose) lorsque
votre classe posséde un destructeur, que vous êtes sûr que l'objet ne sera
plus utilisé, que celui-ci occupe une place importante en mémoire et que
vous n'êtes pas sûr que le code appelant appellera votre méthode Dispose().
Ca permettra de libérer la place utilisée par l'objet dés le premier appel
au GC, alors que sinon elle ne serait libérée que lors du second appel. Bref
cette situation n'arrive pas tous les jours.


> 3)


Je suis d'accord.
.
> 4) Accessoirement, je suppose qu'il y a un moyen (simple) de vérifier si
un
> objet implémente une interface (réflexion) ?


Utilisez les mots-clefs is ou as :
IDisposable objectToDispose = myObject as IDisposable;
if (objectToDispose != null)
objectToDispose.Dispose();

--
Zazar
Avatar
Pascal Mercier
Bonjour,

Voici quelques règles générales à suivre :
1. Le code .NET (indépendemment du langage) est managé = fini les "je libère
les ressources moi-même". Donc pas de toto=null dans un Dispose, ça ne sert
à rien.
2. Ne pas utiliser de destructeur, notamment parce que rien ne garanti de
l'exécution exacte de la méthode. Encore une fois le GC (Garbage Collector)
s'occupe pour vous de détruire l'objet.
3. Implémenter IDispose pour 1) fermer les handles qui n'ont plus besoin
d'être conservés ouverts (connexions de base de données, fichiers, etc, 2)
libérer les ressources non managés (références à des objets COM, etc).
4. Ouvrir les connexions aux bases de données le plus tard possible et les
refermer le plus tôt dès que possible. En clair, une connexion ne devrait
pas avoir une durée de vie qui va au delà de la méthode. Le connexion pool
est là pour la performance.
5. En C#, utilisez le mot clé using (...) {..} pour appeler implicitement
les méthodes Dispose(). Ca évite d'oublier.

Pour info, voici ce qui est dit sur les destructeurs dans le doc du FW 1.1:
Using Destructors to Release Resources
In general, you should NOT be as concerned about memory management as you
would with C++. This is because the .NET Framework garbage collector
implicitly manages the allocation and release of memory for your objects.
However, when your application encapsulates UNMANAGED resources such as
windows, files, and network connections, you should use destructors to free
those resources. When the object is eligible for destruction, the garbage
collector runs the object's Finalize method.

Etes-vous dans le cas d'utilisation de ressources non managés ? Il semble
que non.

Tester si une interface est implémentée (C#):
IMonInterface o = obj as IMonInterface
if (o!=null)
{
// o implémente IMonInterface
}

Pascal Mercier
Microsoft France - MCS

"Johnny" wrote in message
news:4159c0e9$0$2232$
Bonjour ou bonsoir,

Je crée une classe MaClasse implémentant l'interface IDisposable.
Vous trouverez (sans entrer dans le détail) l'allure de mon code à la fin


de
mon message.
Je me pose quelques questions au sujet du contenu de la méthode public


void
Dispose( bool disposing )

1) Ma classe contient quelques variables private de type string. Est-ce
qu'il y a un intéret à faire un this.maVariableString = null; ?

2) D'une manière générale, j'envisage de mettre à null tous les objets,
managés ou non, et d'appeller au préalable la methode .Dispose() si et
seulement si l'objet a été crée par la classe ( et bien entendu si l'objet


à
"nullifier" propose la méthode Dispose() (*) ).

3) MaClasse travaille avec une base de données et possède une donnée


private
de type IDbConnection. Cet objet de type IDbConnection est un argument


d'un
constructeur; il est aussi accessible en lecture/écriture (get/set) via


une
propriété. J'envisage donc, dans mon Dispose, de faire un simple
this.MonIdbConnection = null;. Je n'envisage rien d'autre, en particulier
aucun appel à un .Close() ou un .Dispose() car la connexion est partagée :
l'orsque mon objet de type MaClasse est créé, il existe déjà un autre


objet
MaConnexion (de type IDbConenction, ou OleDbConnecttion ou...) et cet


autre
objet "pointe" déjà une base et est "ouvert". Je passe donc MaConnexion au
constructeur de MaClasse, afin de profiter d'une connexion ouverte et donc
de faire l'économie d'une connexion supplémentaire... Est-ce là une bonne
pratique ? Je pose la question car j'ai lu, içi ou là dans quelques posts,
qu'il existerait un mécanisme de "pool de connexion" (**) ? Si ce


mécanisme
est efficace et général, je pourrais alors passer plutôt par une chaine de
connexion, et créer une nouvelle connexion réellement propre à MaClasse,
puis fermer la conenxion dans le Dispose(), et par exemple ne pas supposer
ou vérifer que MaConnexion est ou non ouverte lorsque j'en ai besoin dans
MaClasse...

4) Accessoirement, je suppose qu'il y a un moyen (simple) de vérifier si


un
objet implémente une interface (réflexion) ?

Merci à tous

Johnny

(*) Même chose pour le "Close()" si "Open()" réalisé dans la classe
(**) Avez-vous un (bon) lien à ce sujet ?

//---------------------------------------
//--------------------------------------- Portion de code
//---------------------------------------

public void Dispose()
{
this.Dispose( true );
GC.SuppressFinalize( this );
}

public void Dispose( bool disposing )
{
if( disposing )
{
// Suppression des objets managés
}
// Suppression des objets non managés
}

~MaClasse()
{
this.Dispose( false );
}





Avatar
Dom
Vous pourrez trouver une FAQ : "ADO.NET Connection Pooling FAQ" [1]

Si vous lisez cette FAQ, vous vous arreterez peut-être sur la réponse à
cette question :

When is the connection pool destroyed ?

--> When last connection in the pool is closed the pool is
destroyed.

Or vous écrivez :

4. Ouvrir les connexions aux bases de données le plus tard possible et les
refermer le plus tôt dès que possible. En clair, une connexion ne devrait
pas avoir une durée de vie qui va au delà de la méthode. Le connexion pool
est là pour la performance.



Si la FAQ dit vrai, et que l'application développée travaille seule sur une
base locale
et qu'il n'est jamais besoin de plus d'une connexion, alors faut-il en
conclure que
compter sur le pool est une erreur qui peut couter cher coté performances ?
Dans ce cas précis (et sans doute assez fréquent), n'est-il pas préférable
de
maintenir une connexion ouverte pendant toute la durée d'exécution de
l'application ?

D'une façon plus générale, le pool n'est justifié que s'il est interessant
de travailler en
même temps avec plusieurs connexions, et ce pour une application donnée sur
un poste donné.
Du temps d'ADO, je n'ai jamais travaillé qu'avec une seule connexion à la
base. Cela sans
rencontrer le moindre problème. Et aujourd'hui comme hier, je ne vois pas
l'interêt d'avoir
plusieurs connexions à ma base (pour une instance de l'application). Si vous
pouvez éclairer
ma lanterne..?

[1] http://www.c-sharpcorner.com/Code/2004/May/PoolingNS.asp

"Pascal Mercier" a écrit dans le message de
news:%23np$R$
Bonjour,

Voici quelques règles générales à suivre :
1. Le code .NET (indépendemment du langage) est managé = fini les "je


libère
les ressources moi-même". Donc pas de toto=null dans un Dispose, ça ne


sert
à rien.
2. Ne pas utiliser de destructeur, notamment parce que rien ne garanti de
l'exécution exacte de la méthode. Encore une fois le GC (Garbage


Collector)
s'occupe pour vous de détruire l'objet.
3. Implémenter IDispose pour 1) fermer les handles qui n'ont plus besoin
d'être conservés ouverts (connexions de base de données, fichiers, etc, 2)
libérer les ressources non managés (références à des objets COM, etc).
4. Ouvrir les connexions aux bases de données le plus tard possible et les
refermer le plus tôt dès que possible. En clair, une connexion ne devrait
pas avoir une durée de vie qui va au delà de la méthode. Le connexion pool
est là pour la performance.
5. En C#, utilisez le mot clé using (...) {..} pour appeler implicitement
les méthodes Dispose(). Ca évite d'oublier.

Pour info, voici ce qui est dit sur les destructeurs dans le doc du FW


1.1:
Using Destructors to Release Resources
In general, you should NOT be as concerned about memory management as you
would with C++. This is because the .NET Framework garbage collector
implicitly manages the allocation and release of memory for your objects.
However, when your application encapsulates UNMANAGED resources such as
windows, files, and network connections, you should use destructors to


free
those resources. When the object is eligible for destruction, the garbage
collector runs the object's Finalize method.

Etes-vous dans le cas d'utilisation de ressources non managés ? Il semble
que non.

Tester si une interface est implémentée (C#):
IMonInterface o = obj as IMonInterface
if (o!=null)
{
// o implémente IMonInterface
}

Pascal Mercier
Microsoft France - MCS

"Johnny" wrote in message
news:4159c0e9$0$2232$
> Bonjour ou bonsoir,
>
> Je crée une classe MaClasse implémentant l'interface IDisposable.
> Vous trouverez (sans entrer dans le détail) l'allure de mon code à la


fin
de
> mon message.
> Je me pose quelques questions au sujet du contenu de la méthode public
void
> Dispose( bool disposing )
>
> 1) Ma classe contient quelques variables private de type string. Est-ce
> qu'il y a un intéret à faire un this.maVariableString = null; ?
>
> 2) D'une manière générale, j'envisage de mettre à null tous les objets,
> managés ou non, et d'appeller au préalable la methode .Dispose() si et
> seulement si l'objet a été crée par la classe ( et bien entendu si


l'objet
à
> "nullifier" propose la méthode Dispose() (*) ).
>
> 3) MaClasse travaille avec une base de données et possède une donnée
private
> de type IDbConnection. Cet objet de type IDbConnection est un argument
d'un
> constructeur; il est aussi accessible en lecture/écriture (get/set) via
une
> propriété. J'envisage donc, dans mon Dispose, de faire un simple
> this.MonIdbConnection = null;. Je n'envisage rien d'autre, en


particulier
> aucun appel à un .Close() ou un .Dispose() car la connexion est partagée


:
> l'orsque mon objet de type MaClasse est créé, il existe déjà un autre
objet
> MaConnexion (de type IDbConenction, ou OleDbConnecttion ou...) et cet
autre
> objet "pointe" déjà une base et est "ouvert". Je passe donc MaConnexion


au
> constructeur de MaClasse, afin de profiter d'une connexion ouverte et


donc
> de faire l'économie d'une connexion supplémentaire... Est-ce là une


bonne
> pratique ? Je pose la question car j'ai lu, içi ou là dans quelques


posts,
> qu'il existerait un mécanisme de "pool de connexion" (**) ? Si ce
mécanisme
> est efficace et général, je pourrais alors passer plutôt par une chaine


de
> connexion, et créer une nouvelle connexion réellement propre à MaClasse,
> puis fermer la conenxion dans le Dispose(), et par exemple ne pas


supposer
> ou vérifer que MaConnexion est ou non ouverte lorsque j'en ai besoin


dans
> MaClasse...
>
> 4) Accessoirement, je suppose qu'il y a un moyen (simple) de vérifier si
un
> objet implémente une interface (réflexion) ?
>
> Merci à tous
>
> Johnny
>
> (*) Même chose pour le "Close()" si "Open()" réalisé dans la classe
> (**) Avez-vous un (bon) lien à ce sujet ?
>
> //---------------------------------------
> //--------------------------------------- Portion de code
> //---------------------------------------
>
> public void Dispose()
> {
> this.Dispose( true );
> GC.SuppressFinalize( this );
> }
>
> public void Dispose( bool disposing )
> {
> if( disposing )
> {
> // Suppression des objets managés
> }
> // Suppression des objets non managés
> }
>
> ~MaClasse()
> {
> this.Dispose( false );
> }
>
>
>




Avatar
Piotrek
"Dom" wrote in message
news:415ab498$0$19734$
Vous pourrez trouver une FAQ : "ADO.NET Connection Pooling FAQ" [1]

Si vous lisez cette FAQ, vous vous arreterez peut-être sur la réponse à
cette question :

When is the connection pool destroyed ?

--> When last connection in the pool is closed the pool is
destroyed.

Or vous écrivez :

> 4. Ouvrir les connexions aux bases de données le plus tard possible et


les
> refermer le plus tôt dès que possible. En clair, une connexion ne


devrait
> pas avoir une durée de vie qui va au delà de la méthode. Le connexion


pool
> est là pour la performance.

Si la FAQ dit vrai, et que l'application développée travaille seule sur


une
base locale
et qu'il n'est jamais besoin de plus d'une connexion, alors faut-il en
conclure que
compter sur le pool est une erreur qui peut couter cher coté performances


?
Dans ce cas précis (et sans doute assez fréquent), n'est-il pas préférable
de
maintenir une connexion ouverte pendant toute la durée d'exécution de
l'application ?

D'une façon plus générale, le pool n'est justifié que s'il est interessant
de travailler en
même temps avec plusieurs connexions, et ce pour une application donnée


sur
un poste donné.
Du temps d'ADO, je n'ai jamais travaillé qu'avec une seule connexion à la
base. Cela sans
rencontrer le moindre problème. Et aujourd'hui comme hier, je ne vois pas
l'interêt d'avoir
plusieurs connexions à ma base (pour une instance de l'application). Si


vous
pouvez éclairer
ma lanterne..?



Il faut pas croire tout ce qui est ecrit :)

L'interet du pool serait tres limite dans ce cas la

Voila qui est techniquement plus complet et juste
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/cpguide/html/cpconConnectionPoolingForSQLServerNETDataProvider.asp

Crois moi j'etais comme toi, je fonctionnais avec une seule connection
ouverten en permanence, j'ai fait un systeme assez complexe (pour pouvoir
gerer les readers) qui marchait parfaitement: les performances etaient les
meme (+/- 4%) avec l'inconvenient en plus d'avoir en permanence un objet
tres lourd gaspillant un peu de memoire sur le client.(en asp c'est
nettement plus critique!)

J'ai enleve ce systeme: le code est plus propre et tout aussi performant

Pourquoi t'en prive tu? de toute facon tu utilise ce pool sans meme le
savoir :p
Avatar
Zazar
Bonjour,

2. Ne pas utiliser de destructeur, notamment parce que rien ne garanti de
l'exécution exacte de la méthode. Encore une fois le GC (Garbage


Collector)
s'occupe pour vous de détruire l'objet.


Qu'est ce que vous entendez par éxécution "exacte" ?
Il est garanti que le destructeur/la méthode Finalize sera exécute à moins
qu'il n'ait été explicitement demandé que ce ne soit pas le cas par un
GC.SuppressFinalize().
De plus, un destructeur ne sert pas à détruire l'objet, donc même si le GC
détruit l'objet, ça n'empêche pas que la présence d'un destructeur soit
indispensable dans certains cas.

--
Zazar
Avatar
Zazar
Bonjour,

Vous pourrez trouver une FAQ : "ADO.NET Connection Pooling FAQ" [1]

Si vous lisez cette FAQ, vous vous arreterez peut-être sur la réponse à
cette question :

When is the connection pool destroyed ?

--> When last connection in the pool is closed the pool is
destroyed.




C'est une erreur, le pool est détruit lorsque le domaine d'application
auquel il appartient est déchargé. En gros, dans la plupart des cas c'est
quand le process se termine.

--
Zazar
Avatar
Vincent Lascaux
> 1. Le code .NET (indépendemment du langage) est managé = fini les "je
libère
les ressources moi-même". Donc pas de toto=null dans un Dispose, ça ne
sert
à rien.



C'est plutot fini le "je libère la mémoire moi même" et bonjour le "je
libère toutes les autres ressources moi même" (en particulier plus de RAII).
Bienvenu au try { /* ... */ } finally { } dans tous les sens ;')

--
Vincent
Avatar
Pascal Mercier
Comme indiqué dans mon post initial, l'utilisation d'un destructeur n'est
motivé que par une seule raison : l'utilisation de ressources non managées.
Donc, le débat se résume à :
1) vous n'utilisez pas de ressources managées = rien à faire de spécial,
sauf éventuellement implémenter IDispose pour disposer des ressources
(connexion de base de données par exemple)
ou
2) vous utilisez des ressources managées = utilisez Finalize ou un
destructeur pour libérer ces ressources

Et il est vrai que j'ai été imprécis : en effet le destructeur ne sert pas à
détruire l'objet.

Cordialement,

Pascal Mercier
Microsoft France - MCS

"Zazar" wrote in message
news:#
Bonjour,

> 2. Ne pas utiliser de destructeur, notamment parce que rien ne garanti


de
> l'exécution exacte de la méthode. Encore une fois le GC (Garbage
Collector)
> s'occupe pour vous de détruire l'objet.
Qu'est ce que vous entendez par éxécution "exacte" ?
Il est garanti que le destructeur/la méthode Finalize sera exécute à moins
qu'il n'ait été explicitement demandé que ce ne soit pas le cas par un
GC.SuppressFinalize().
De plus, un destructeur ne sert pas à détruire l'objet, donc même si le GC
détruit l'objet, ça n'empêche pas que la présence d'un destructeur soit
indispensable dans certains cas.

--
Zazar




Avatar
Pascal Mercier
Voilà des articles sur le connexion pooling :
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/cpguide/html/cpconconnectionpoolingforsqlservernetdataprovider.asp
(avec SQL Server)
et
http://msdn.microsoft.com/library/en-us/cpguide/html/cpconconnectionpoolingforoledbnetdataprovider.asp?frame=true
(avec OLE DB)
et
http://msdn.microsoft.com/library/en-us/cpguide/html/cpconconnectionpoolingfornetdataproviderfororacle.asp?frame=true
(avec Oracle)

En résumé :
Ce qui est dit :
1) Le connexion pooling améliore les performances de façon significative
2) on referme dès que possible une connexion ouverte. Je persiste et signe :
une connexion s'ouvre et se ferme dans la même méthode.
3) Un pool de connexion est supprimé avec la fin du processus : "Once
created, connection pools are not destroyed until the active process ends.
Maintenance of inactive or empty pools involves minimal system overhead.".
En gros, quand l'application domain meurt, le pool de connexion meurt.
4) il y a un connexion pool par connection string.

Cordialement,

Pascal Mercier
Microsoft France - MCS
"Dom" wrote in message
news:415ab498$0$19734$
Vous pourrez trouver une FAQ : "ADO.NET Connection Pooling FAQ" [1]

Si vous lisez cette FAQ, vous vous arreterez peut-être sur la réponse à
cette question :

When is the connection pool destroyed ?

--> When last connection in the pool is closed the pool is
destroyed.

Or vous écrivez :

> 4. Ouvrir les connexions aux bases de données le plus tard possible et


les
> refermer le plus tôt dès que possible. En clair, une connexion ne


devrait
> pas avoir une durée de vie qui va au delà de la méthode. Le connexion


pool
> est là pour la performance.

Si la FAQ dit vrai, et que l'application développée travaille seule sur


une
base locale
et qu'il n'est jamais besoin de plus d'une connexion, alors faut-il en
conclure que
compter sur le pool est une erreur qui peut couter cher coté performances


?
Dans ce cas précis (et sans doute assez fréquent), n'est-il pas préférable
de
maintenir une connexion ouverte pendant toute la durée d'exécution de
l'application ?

D'une façon plus générale, le pool n'est justifié que s'il est interessant
de travailler en
même temps avec plusieurs connexions, et ce pour une application donnée


sur
un poste donné.
Du temps d'ADO, je n'ai jamais travaillé qu'avec une seule connexion à la
base. Cela sans
rencontrer le moindre problème. Et aujourd'hui comme hier, je ne vois pas
l'interêt d'avoir
plusieurs connexions à ma base (pour une instance de l'application). Si


vous
pouvez éclairer
ma lanterne..?

[1] http://www.c-sharpcorner.com/Code/2004/May/PoolingNS.asp

"Pascal Mercier" a écrit dans le message


de
news:%23np$R$
> Bonjour,
>
> Voici quelques règles générales à suivre :
> 1. Le code .NET (indépendemment du langage) est managé = fini les "je
libère
> les ressources moi-même". Donc pas de toto=null dans un Dispose, ça ne
sert
> à rien.
> 2. Ne pas utiliser de destructeur, notamment parce que rien ne garanti


de
> l'exécution exacte de la méthode. Encore une fois le GC (Garbage
Collector)
> s'occupe pour vous de détruire l'objet.
> 3. Implémenter IDispose pour 1) fermer les handles qui n'ont plus besoin
> d'être conservés ouverts (connexions de base de données, fichiers, etc,


2)
> libérer les ressources non managés (références à des objets COM, etc).
> 4. Ouvrir les connexions aux bases de données le plus tard possible et


les
> refermer le plus tôt dès que possible. En clair, une connexion ne


devrait
> pas avoir une durée de vie qui va au delà de la méthode. Le connexion


pool
> est là pour la performance.
> 5. En C#, utilisez le mot clé using (...) {..} pour appeler


implicitement
> les méthodes Dispose(). Ca évite d'oublier.
>
> Pour info, voici ce qui est dit sur les destructeurs dans le doc du FW
1.1:
> Using Destructors to Release Resources
> In general, you should NOT be as concerned about memory management as


you
> would with C++. This is because the .NET Framework garbage collector
> implicitly manages the allocation and release of memory for your


objects.
> However, when your application encapsulates UNMANAGED resources such as
> windows, files, and network connections, you should use destructors to
free
> those resources. When the object is eligible for destruction, the


garbage
> collector runs the object's Finalize method.
>
> Etes-vous dans le cas d'utilisation de ressources non managés ? Il


semble
> que non.
>
> Tester si une interface est implémentée (C#):
> IMonInterface o = obj as IMonInterface
> if (o!=null)
> {
> // o implémente IMonInterface
> }
>
> Pascal Mercier
> Microsoft France - MCS
>
> "Johnny" wrote in message
> news:4159c0e9$0$2232$
> > Bonjour ou bonsoir,
> >
> > Je crée une classe MaClasse implémentant l'interface IDisposable.
> > Vous trouverez (sans entrer dans le détail) l'allure de mon code à la
fin
> de
> > mon message.
> > Je me pose quelques questions au sujet du contenu de la méthode public
> void
> > Dispose( bool disposing )
> >
> > 1) Ma classe contient quelques variables private de type string.


Est-ce
> > qu'il y a un intéret à faire un this.maVariableString = null; ?
> >
> > 2) D'une manière générale, j'envisage de mettre à null tous les


objets,
> > managés ou non, et d'appeller au préalable la methode .Dispose() si et
> > seulement si l'objet a été crée par la classe ( et bien entendu si
l'objet
> à
> > "nullifier" propose la méthode Dispose() (*) ).
> >
> > 3) MaClasse travaille avec une base de données et possède une donnée
> private
> > de type IDbConnection. Cet objet de type IDbConnection est un argument
> d'un
> > constructeur; il est aussi accessible en lecture/écriture (get/set)


via
> une
> > propriété. J'envisage donc, dans mon Dispose, de faire un simple
> > this.MonIdbConnection = null;. Je n'envisage rien d'autre, en
particulier
> > aucun appel à un .Close() ou un .Dispose() car la connexion est


partagée
:
> > l'orsque mon objet de type MaClasse est créé, il existe déjà un autre
> objet
> > MaConnexion (de type IDbConenction, ou OleDbConnecttion ou...) et cet
> autre
> > objet "pointe" déjà une base et est "ouvert". Je passe donc


MaConnexion
au
> > constructeur de MaClasse, afin de profiter d'une connexion ouverte et
donc
> > de faire l'économie d'une connexion supplémentaire... Est-ce là une
bonne
> > pratique ? Je pose la question car j'ai lu, içi ou là dans quelques
posts,
> > qu'il existerait un mécanisme de "pool de connexion" (**) ? Si ce
> mécanisme
> > est efficace et général, je pourrais alors passer plutôt par une


chaine
de
> > connexion, et créer une nouvelle connexion réellement propre à


MaClasse,
> > puis fermer la conenxion dans le Dispose(), et par exemple ne pas
supposer
> > ou vérifer que MaConnexion est ou non ouverte lorsque j'en ai besoin
dans
> > MaClasse...
> >
> > 4) Accessoirement, je suppose qu'il y a un moyen (simple) de vérifier


si
> un
> > objet implémente une interface (réflexion) ?
> >
> > Merci à tous
> >
> > Johnny
> >
> > (*) Même chose pour le "Close()" si "Open()" réalisé dans la classe
> > (**) Avez-vous un (bon) lien à ce sujet ?
> >
> > //---------------------------------------
> > //--------------------------------------- Portion de code
> > //---------------------------------------
> >
> > public void Dispose()
> > {
> > this.Dispose( true );
> > GC.SuppressFinalize( this );
> > }
> >
> > public void Dispose( bool disposing )
> > {
> > if( disposing )
> > {
> > // Suppression des objets managés
> > }
> > // Suppression des objets non managés
> > }
> >
> > ~MaClasse()
> > {
> > this.Dispose( false );
> > }
> >
> >
> >
>
>




1 2