Bonjour tout le monde !
Je développe actuellement une classe qui contient des variables membres
privées de type IDisposable.
Faut-il dans cette classe ajouter l'implémentation de l'interface
IDisposable() et appeller Dispose() pour toutes les variables membres ?
public class MaClasse : IDisposable
{
private UneClasseIDisposable classe1;
private UneClasseIDisposable2 classe2;
public virtual void Dispose()
{
if (classe1 != null)
classe1.Dispose();
if (classe2 != null)
classe2.Dispose();
}
}
Est-ce correct ?
Une autre question complémentaire :
Faut-il mettre null dans les variables que l'on "Dispose".
Bonjour tout le monde !
Je développe actuellement une classe qui contient des variables membres
privées de type IDisposable.
Faut-il dans cette classe ajouter l'implémentation de l'interface
IDisposable() et appeller Dispose() pour toutes les variables membres ?
public class MaClasse : IDisposable
{
private UneClasseIDisposable classe1;
private UneClasseIDisposable2 classe2;
public virtual void Dispose()
{
if (classe1 != null)
classe1.Dispose();
if (classe2 != null)
classe2.Dispose();
}
}
Est-ce correct ?
Une autre question complémentaire :
Faut-il mettre null dans les variables que l'on "Dispose".
Bonjour tout le monde !
Je développe actuellement une classe qui contient des variables membres
privées de type IDisposable.
Faut-il dans cette classe ajouter l'implémentation de l'interface
IDisposable() et appeller Dispose() pour toutes les variables membres ?
public class MaClasse : IDisposable
{
private UneClasseIDisposable classe1;
private UneClasseIDisposable2 classe2;
public virtual void Dispose()
{
if (classe1 != null)
classe1.Dispose();
if (classe2 != null)
classe2.Dispose();
}
}
Est-ce correct ?
Une autre question complémentaire :
Faut-il mettre null dans les variables que l'on "Dispose".
On Sun, 02 Jul 2006 11:52:53 +0200, Gilles TOURREAU wrote:Bonjour tout le monde !
Je développe actuellement une classe qui contient des variables membres
privées de type IDisposable.
Faut-il dans cette classe ajouter l'implémentation de l'interface
IDisposable() et appeller Dispose() pour toutes les variables membres ?
Oui. Toute instance d'une classe implémentant IDisposable doit etre
"disposée" des qu'elle n'est plus utilisée. Dans le cas ou cette instance
est une variable membre d'un object, elle doit etre "disposée" lorsque son
objet parent n'est plus utile. Le pattern permettant de faire ca en .NET
est le Dispoable Pattern.public class MaClasse : IDisposable
{
private UneClasseIDisposable classe1;
private UneClasseIDisposable2 classe2;
public virtual void Dispose()
{
if (classe1 != null)
classe1.Dispose();
if (classe2 != null)
classe2.Dispose();
}
}
Est-ce correct ?
OuiUne autre question complémentaire :
Faut-il mettre null dans les variables que l'on "Dispose".
En général non, ce n'est pas utile. Cela peux etre utile si
- l'objet disposé utilise beaucoup de mémoire et
- l'objet disposé est une variable locale a une fonction et
- l'objet disposé est disposé au beau milieu de cette fonction et
- cette fonction va avoir besoin d'allouer de la memoire apres que l'objet
soit disposé
Dans ce cas, le mettre a null permettra au GC de se rendre compte que plus
personne ne référence cet object ce qui lui permettra de libérer la
mémoire
utilisé par cet objet dans le cas ou la reste de la fonction en question a
besoin de plus de mémoire qu'il n'y a de disponible. Ce genre de situation
est tres tres rare cela dit. Rien ne t'empeche cependant de mettre tes
variables a null si tu le souhaite.
On Sun, 02 Jul 2006 11:52:53 +0200, Gilles TOURREAU wrote:
Bonjour tout le monde !
Je développe actuellement une classe qui contient des variables membres
privées de type IDisposable.
Faut-il dans cette classe ajouter l'implémentation de l'interface
IDisposable() et appeller Dispose() pour toutes les variables membres ?
Oui. Toute instance d'une classe implémentant IDisposable doit etre
"disposée" des qu'elle n'est plus utilisée. Dans le cas ou cette instance
est une variable membre d'un object, elle doit etre "disposée" lorsque son
objet parent n'est plus utile. Le pattern permettant de faire ca en .NET
est le Dispoable Pattern.
public class MaClasse : IDisposable
{
private UneClasseIDisposable classe1;
private UneClasseIDisposable2 classe2;
public virtual void Dispose()
{
if (classe1 != null)
classe1.Dispose();
if (classe2 != null)
classe2.Dispose();
}
}
Est-ce correct ?
Oui
Une autre question complémentaire :
Faut-il mettre null dans les variables que l'on "Dispose".
En général non, ce n'est pas utile. Cela peux etre utile si
- l'objet disposé utilise beaucoup de mémoire et
- l'objet disposé est une variable locale a une fonction et
- l'objet disposé est disposé au beau milieu de cette fonction et
- cette fonction va avoir besoin d'allouer de la memoire apres que l'objet
soit disposé
Dans ce cas, le mettre a null permettra au GC de se rendre compte que plus
personne ne référence cet object ce qui lui permettra de libérer la
mémoire
utilisé par cet objet dans le cas ou la reste de la fonction en question a
besoin de plus de mémoire qu'il n'y a de disponible. Ce genre de situation
est tres tres rare cela dit. Rien ne t'empeche cependant de mettre tes
variables a null si tu le souhaite.
On Sun, 02 Jul 2006 11:52:53 +0200, Gilles TOURREAU wrote:Bonjour tout le monde !
Je développe actuellement une classe qui contient des variables membres
privées de type IDisposable.
Faut-il dans cette classe ajouter l'implémentation de l'interface
IDisposable() et appeller Dispose() pour toutes les variables membres ?
Oui. Toute instance d'une classe implémentant IDisposable doit etre
"disposée" des qu'elle n'est plus utilisée. Dans le cas ou cette instance
est une variable membre d'un object, elle doit etre "disposée" lorsque son
objet parent n'est plus utile. Le pattern permettant de faire ca en .NET
est le Dispoable Pattern.public class MaClasse : IDisposable
{
private UneClasseIDisposable classe1;
private UneClasseIDisposable2 classe2;
public virtual void Dispose()
{
if (classe1 != null)
classe1.Dispose();
if (classe2 != null)
classe2.Dispose();
}
}
Est-ce correct ?
OuiUne autre question complémentaire :
Faut-il mettre null dans les variables que l'on "Dispose".
En général non, ce n'est pas utile. Cela peux etre utile si
- l'objet disposé utilise beaucoup de mémoire et
- l'objet disposé est une variable locale a une fonction et
- l'objet disposé est disposé au beau milieu de cette fonction et
- cette fonction va avoir besoin d'allouer de la memoire apres que l'objet
soit disposé
Dans ce cas, le mettre a null permettra au GC de se rendre compte que plus
personne ne référence cet object ce qui lui permettra de libérer la
mémoire
utilisé par cet objet dans le cas ou la reste de la fonction en question a
besoin de plus de mémoire qu'il n'y a de disponible. Ce genre de situation
est tres tres rare cela dit. Rien ne t'empeche cependant de mettre tes
variables a null si tu le souhaite.
Bonjour tout le monde !
Je développe actuellement une classe qui contient des variables membres
privées de type IDisposable.
Faut-il dans cette classe ajouter l'implémentation de l'interface
IDisposable() et appeller Dispose() pour toutes les variables membres ?
Exemple :
public class MaClasse : IDisposable
{
private UneClasseIDisposable classe1;
private UneClasseIDisposable2 classe2;
public virtual void Dispose()
{
if (classe1 != null)
classe1.Dispose();
if (classe2 != null)
classe2.Dispose();
}
}
Est-ce correct ?
Une autre question complémentaire :
Faut-il mettre null dans les variables que l'on "Dispose".
Exemple :
if (classe2 != null)
{
classe2.Dispose();
classe2 = null;
}
En vous remerciant par avance de vos lumières !
--
Gilles TOURREAU
Responsable informatique
Société P.O.S
Spécialiste en motoculture depuis + de 30 ans !
http://www.pos.fr
Bonjour tout le monde !
Je développe actuellement une classe qui contient des variables membres
privées de type IDisposable.
Faut-il dans cette classe ajouter l'implémentation de l'interface
IDisposable() et appeller Dispose() pour toutes les variables membres ?
Exemple :
public class MaClasse : IDisposable
{
private UneClasseIDisposable classe1;
private UneClasseIDisposable2 classe2;
public virtual void Dispose()
{
if (classe1 != null)
classe1.Dispose();
if (classe2 != null)
classe2.Dispose();
}
}
Est-ce correct ?
Une autre question complémentaire :
Faut-il mettre null dans les variables que l'on "Dispose".
Exemple :
if (classe2 != null)
{
classe2.Dispose();
classe2 = null;
}
En vous remerciant par avance de vos lumières !
--
Gilles TOURREAU
Responsable informatique
gilles.tourreau@pos.fr
Société P.O.S
Spécialiste en motoculture depuis + de 30 ans !
http://www.pos.fr
Bonjour tout le monde !
Je développe actuellement une classe qui contient des variables membres
privées de type IDisposable.
Faut-il dans cette classe ajouter l'implémentation de l'interface
IDisposable() et appeller Dispose() pour toutes les variables membres ?
Exemple :
public class MaClasse : IDisposable
{
private UneClasseIDisposable classe1;
private UneClasseIDisposable2 classe2;
public virtual void Dispose()
{
if (classe1 != null)
classe1.Dispose();
if (classe2 != null)
classe2.Dispose();
}
}
Est-ce correct ?
Une autre question complémentaire :
Faut-il mettre null dans les variables que l'on "Dispose".
Exemple :
if (classe2 != null)
{
classe2.Dispose();
classe2 = null;
}
En vous remerciant par avance de vos lumières !
--
Gilles TOURREAU
Responsable informatique
Société P.O.S
Spécialiste en motoculture depuis + de 30 ans !
http://www.pos.fr
on m'a conseillé, en formation c# 2, de laisser le GC faire son travail,
donc de ne pas appeler le Dispose.
l'explication, si je me souviens bien (ca fait 1 an !!!) : le fait de faire
un dispose appel et force le GC,
si on ne le fait pas (le dispose), l'objet
est quand meme purger par le GC mais quand, ca on ne sait pas.
le principe est le suivant : le GC passe et si il voit un objet qui n'est
plus lié à rien, il le purge et ainsi de suite. dans ton cas, tu as un objet
(A) qui en contient d'autre (B et C) : donc si casse le lien de ton objet A,
le GC va le purger, et lors du passage suivant, il purgera les objets B et C
et ainsi de suite.
on m'avait conseillé de ne pas faire les dispose car d'une manière générale,
ca chamboulé l'organisation du GC,
on m'a conseillé, en formation c# 2, de laisser le GC faire son travail,
donc de ne pas appeler le Dispose.
l'explication, si je me souviens bien (ca fait 1 an !!!) : le fait de faire
un dispose appel et force le GC,
si on ne le fait pas (le dispose), l'objet
est quand meme purger par le GC mais quand, ca on ne sait pas.
le principe est le suivant : le GC passe et si il voit un objet qui n'est
plus lié à rien, il le purge et ainsi de suite. dans ton cas, tu as un objet
(A) qui en contient d'autre (B et C) : donc si casse le lien de ton objet A,
le GC va le purger, et lors du passage suivant, il purgera les objets B et C
et ainsi de suite.
on m'avait conseillé de ne pas faire les dispose car d'une manière générale,
ca chamboulé l'organisation du GC,
on m'a conseillé, en formation c# 2, de laisser le GC faire son travail,
donc de ne pas appeler le Dispose.
l'explication, si je me souviens bien (ca fait 1 an !!!) : le fait de faire
un dispose appel et force le GC,
si on ne le fait pas (le dispose), l'objet
est quand meme purger par le GC mais quand, ca on ne sait pas.
le principe est le suivant : le GC passe et si il voit un objet qui n'est
plus lié à rien, il le purge et ainsi de suite. dans ton cas, tu as un objet
(A) qui en contient d'autre (B et C) : donc si casse le lien de ton objet A,
le GC va le purger, et lors du passage suivant, il purgera les objets B et C
et ainsi de suite.
on m'avait conseillé de ne pas faire les dispose car d'une manière générale,
ca chamboulé l'organisation du GC,
On Mon, 17 Jul 2006 02:47:01 -0700, Laurent wrote:
> on m'a conseillé, en formation c# 2, de laisser le GC faire son travail,
> donc de ne pas appeler le Dispose.
> l'explication, si je me souviens bien (ca fait 1 an !!!) : le fait de faire
> un dispose appel et force le GC,
Je pense que tu confond avec GC.Collect(). Appeler Dispose() ne fait
qu'executer la méthode Dispose(), n'a strictement rien a voir avec le GC et
ne force absoument pas le GC a rentrer en action. Une fois Dispose()
appelé, l'objet est toujours la en mémoire et sera purgé plus tard par le
GC lorsqu'il se sentira d'humeur a le faire.
> si on ne le fait pas (le dispose), l'objet
> est quand meme purger par le GC mais quand, ca on ne sait pas.
Meme si on appele Dispose(), l'objet est purgé plus tard par le GC et on ne
sait pas quand.
> le principe est le suivant : le GC passe et si il voit un objet qui n'est
> plus lié à rien, il le purge et ainsi de suite. dans ton cas, tu as un objet
> (A) qui en contient d'autre (B et C) : donc si casse le lien de ton objet A,
> le GC va le purger, et lors du passage suivant, il purgera les objets B et C
> et ainsi de suite.
Oui. Mais il y a un probleme pour les objet contenant des ressources
non-managées (des Handles crée via P/Invoke, une connection vers une base
de donnée, un fichier ouvert...). Le GC ne s'occupe que de la mémoire et ne
sais pas comment libérer ces ressources. Les classes contenant des
ressources non-managées doivent donc implémenter un Finalizer qui s'occupe
de libérer ces ressources. Lorsque le GC passe, si il voit que l'objet a un
Finalizer, il l'appele d'abord avant de supprimer l'objet. Ce mécanisme
permet d'éviter des fuites de ressources.
Seulement, comme tu l'as dit au dessus, le GC peux prendre son temps avant
de passer et conserver une ressource non-managée dont on n'a plus besoin
pendant un temps potentiellement tres long est généralement une tres
mauvaise idée. Donc ces ressources doivent etre libérées des que possible
sans attendre le GC. D'ou l'idée de la méthode Dispose(). La méthode
Dispose() est la pour permettre a l'utilisateur d'indiquer a un objet qu'il
n'a plus besoin de lui et que l'objet doit libérer ces ressoures
non-managées immédiatement. En général la méthode Dispose(), en plus de
libérer les ressources non-managées, supprime également le Finalizer, qui
n'est plus nécéssaire vu que les ressources non-managées ont déja été
libérer, avec GC.SuppressFinalize(). Cela permet au GC de faire son boulot
plus rapidement vu qu'il n'aura pas a appeler le finalizer pour cet objet.
Dans le cas ou l'utilisateur a oublié d'appeler Dispose(), le Finalizer
n'aura pas été supprimé et sera donc appelé par le GC lorsqu'il passera
permettant ainsi de libérer toutes les ressources non-managées.
> on m'avait conseillé de ne pas faire les dispose car d'une manière générale,
> ca chamboulé l'organisation du GC,
Si on t'a vraiment conseillé de ne jamais implémenter ou appeler un
Dispose() quelque soit la situation, alors j'espere que tu n'a pas payé
trop cher pour ta formation car, tres clairement, le formateur n'y
connaissait strictement rien en .NET. Mais, comme dit au dessus, je pense
que tu confond en fait avec GC.Collect() qui est effectivement une méthode
a ne jamais appeler sauf situation vraiment exceptionnelle.
On Mon, 17 Jul 2006 02:47:01 -0700, Laurent wrote:
> on m'a conseillé, en formation c# 2, de laisser le GC faire son travail,
> donc de ne pas appeler le Dispose.
> l'explication, si je me souviens bien (ca fait 1 an !!!) : le fait de faire
> un dispose appel et force le GC,
Je pense que tu confond avec GC.Collect(). Appeler Dispose() ne fait
qu'executer la méthode Dispose(), n'a strictement rien a voir avec le GC et
ne force absoument pas le GC a rentrer en action. Une fois Dispose()
appelé, l'objet est toujours la en mémoire et sera purgé plus tard par le
GC lorsqu'il se sentira d'humeur a le faire.
> si on ne le fait pas (le dispose), l'objet
> est quand meme purger par le GC mais quand, ca on ne sait pas.
Meme si on appele Dispose(), l'objet est purgé plus tard par le GC et on ne
sait pas quand.
> le principe est le suivant : le GC passe et si il voit un objet qui n'est
> plus lié à rien, il le purge et ainsi de suite. dans ton cas, tu as un objet
> (A) qui en contient d'autre (B et C) : donc si casse le lien de ton objet A,
> le GC va le purger, et lors du passage suivant, il purgera les objets B et C
> et ainsi de suite.
Oui. Mais il y a un probleme pour les objet contenant des ressources
non-managées (des Handles crée via P/Invoke, une connection vers une base
de donnée, un fichier ouvert...). Le GC ne s'occupe que de la mémoire et ne
sais pas comment libérer ces ressources. Les classes contenant des
ressources non-managées doivent donc implémenter un Finalizer qui s'occupe
de libérer ces ressources. Lorsque le GC passe, si il voit que l'objet a un
Finalizer, il l'appele d'abord avant de supprimer l'objet. Ce mécanisme
permet d'éviter des fuites de ressources.
Seulement, comme tu l'as dit au dessus, le GC peux prendre son temps avant
de passer et conserver une ressource non-managée dont on n'a plus besoin
pendant un temps potentiellement tres long est généralement une tres
mauvaise idée. Donc ces ressources doivent etre libérées des que possible
sans attendre le GC. D'ou l'idée de la méthode Dispose(). La méthode
Dispose() est la pour permettre a l'utilisateur d'indiquer a un objet qu'il
n'a plus besoin de lui et que l'objet doit libérer ces ressoures
non-managées immédiatement. En général la méthode Dispose(), en plus de
libérer les ressources non-managées, supprime également le Finalizer, qui
n'est plus nécéssaire vu que les ressources non-managées ont déja été
libérer, avec GC.SuppressFinalize(). Cela permet au GC de faire son boulot
plus rapidement vu qu'il n'aura pas a appeler le finalizer pour cet objet.
Dans le cas ou l'utilisateur a oublié d'appeler Dispose(), le Finalizer
n'aura pas été supprimé et sera donc appelé par le GC lorsqu'il passera
permettant ainsi de libérer toutes les ressources non-managées.
> on m'avait conseillé de ne pas faire les dispose car d'une manière générale,
> ca chamboulé l'organisation du GC,
Si on t'a vraiment conseillé de ne jamais implémenter ou appeler un
Dispose() quelque soit la situation, alors j'espere que tu n'a pas payé
trop cher pour ta formation car, tres clairement, le formateur n'y
connaissait strictement rien en .NET. Mais, comme dit au dessus, je pense
que tu confond en fait avec GC.Collect() qui est effectivement une méthode
a ne jamais appeler sauf situation vraiment exceptionnelle.
On Mon, 17 Jul 2006 02:47:01 -0700, Laurent wrote:
> on m'a conseillé, en formation c# 2, de laisser le GC faire son travail,
> donc de ne pas appeler le Dispose.
> l'explication, si je me souviens bien (ca fait 1 an !!!) : le fait de faire
> un dispose appel et force le GC,
Je pense que tu confond avec GC.Collect(). Appeler Dispose() ne fait
qu'executer la méthode Dispose(), n'a strictement rien a voir avec le GC et
ne force absoument pas le GC a rentrer en action. Une fois Dispose()
appelé, l'objet est toujours la en mémoire et sera purgé plus tard par le
GC lorsqu'il se sentira d'humeur a le faire.
> si on ne le fait pas (le dispose), l'objet
> est quand meme purger par le GC mais quand, ca on ne sait pas.
Meme si on appele Dispose(), l'objet est purgé plus tard par le GC et on ne
sait pas quand.
> le principe est le suivant : le GC passe et si il voit un objet qui n'est
> plus lié à rien, il le purge et ainsi de suite. dans ton cas, tu as un objet
> (A) qui en contient d'autre (B et C) : donc si casse le lien de ton objet A,
> le GC va le purger, et lors du passage suivant, il purgera les objets B et C
> et ainsi de suite.
Oui. Mais il y a un probleme pour les objet contenant des ressources
non-managées (des Handles crée via P/Invoke, une connection vers une base
de donnée, un fichier ouvert...). Le GC ne s'occupe que de la mémoire et ne
sais pas comment libérer ces ressources. Les classes contenant des
ressources non-managées doivent donc implémenter un Finalizer qui s'occupe
de libérer ces ressources. Lorsque le GC passe, si il voit que l'objet a un
Finalizer, il l'appele d'abord avant de supprimer l'objet. Ce mécanisme
permet d'éviter des fuites de ressources.
Seulement, comme tu l'as dit au dessus, le GC peux prendre son temps avant
de passer et conserver une ressource non-managée dont on n'a plus besoin
pendant un temps potentiellement tres long est généralement une tres
mauvaise idée. Donc ces ressources doivent etre libérées des que possible
sans attendre le GC. D'ou l'idée de la méthode Dispose(). La méthode
Dispose() est la pour permettre a l'utilisateur d'indiquer a un objet qu'il
n'a plus besoin de lui et que l'objet doit libérer ces ressoures
non-managées immédiatement. En général la méthode Dispose(), en plus de
libérer les ressources non-managées, supprime également le Finalizer, qui
n'est plus nécéssaire vu que les ressources non-managées ont déja été
libérer, avec GC.SuppressFinalize(). Cela permet au GC de faire son boulot
plus rapidement vu qu'il n'aura pas a appeler le finalizer pour cet objet.
Dans le cas ou l'utilisateur a oublié d'appeler Dispose(), le Finalizer
n'aura pas été supprimé et sera donc appelé par le GC lorsqu'il passera
permettant ainsi de libérer toutes les ressources non-managées.
> on m'avait conseillé de ne pas faire les dispose car d'une manière générale,
> ca chamboulé l'organisation du GC,
Si on t'a vraiment conseillé de ne jamais implémenter ou appeler un
Dispose() quelque soit la situation, alors j'espere que tu n'a pas payé
trop cher pour ta formation car, tres clairement, le formateur n'y
connaissait strictement rien en .NET. Mais, comme dit au dessus, je pense
que tu confond en fait avec GC.Collect() qui est effectivement une méthode
a ne jamais appeler sauf situation vraiment exceptionnelle.