DataSet et DataTable implémentent tous deux IDisposable, donc, selon les meilleures pratiques conventionnelles, je devrais appeler leurs méthodes Dispose ().
Cependant, d'après ce que j'ai lu jusqu'à présent, DataSet et DataTable n'ont en fait aucune ressource non gérée, donc Dispose () ne fait pas grand-chose.
De plus, je ne peux pas utiliser simplement using(DataSet myDataSet...)
parce que DataSet a une collection de DataTables.
Donc, pour être sûr, je devrais parcourir myDataSet.Tables, disposer de chacun des DataTables, puis disposer du DataSet.
Alors, vaut-il la peine d'appeler Dispose () sur tous mes DataSets et DataTables?
Addenda:
Pour ceux d'entre vous qui pensent que DataSet doit être supprimé: En général, le modèle de suppression est d'utiliser using
ou try..finally
, car vous voulez garantir que Dispose () sera appelé.
Cependant, cela devient très vite laid pour une collection. Par exemple, que faites-vous si l'un des appels à Dispose () lève une exception? L'avalez-vous (ce qui est "mauvais") pour pouvoir continuer à éliminer l'élément suivant?
Ou, suggérez-vous que j'appelle juste myDataSet.Dispose (), et que j'oublie de supprimer les DataTables dans myDataSet.Tables?
Réponses:
Voici quelques discussions expliquant pourquoi Dispose n'est pas nécessaire pour un DataSet.
Disposer ou ne pas disposer? :
Faut-il appeler Dispose sur les objets DataTable et DataSet? comprend quelques explications d'un MVP:
Comprendre la méthode Dispose et les jeux de données? a un commentaire de l'autorité Scott Allen:
Ainsi, le consensus est qu'il n'y a actuellement aucune bonne raison d'appeler Dispose sur un DataSet.
la source
using
bloc, cela dépend de vous.Mise à jour (1er décembre 2009):
Je voudrais modifier cette réponse et admettre que la réponse originale était erronée.
L'analyse initiale ne s'applique aux objets qui nécessitent la finalisation - et le point que les pratiques ne devraient pas être acceptés à la surface sans précision, en profondeur la compréhension est encore debout.
Cependant, il s'avère que DataSets, DataViews, DataTables suppriment la finalisation dans leurs constructeurs - c'est pourquoi appeler Dispose () sur eux explicitement ne fait rien.
Vraisemblablement, cela se produit parce qu'ils n'ont pas de ressources non gérées; donc malgré le fait que MarshalByValueComponent prend en compte les ressources non gérées, ces implémentations particulières n'ont pas besoin et peuvent donc renoncer à la finalisation.
(Le fait que les auteurs de .NET prennent soin de supprimer la finalisation sur les types mêmes qui occupent normalement le plus de mémoire témoigne de l'importance de cette pratique en général pour les types finalisables.)
Néanmoins, le fait que ces détails soient encore sous-documentés depuis la création du .NET Framework (il y a près de 8 ans) est assez surprenant (que vous êtes essentiellement laissé à vos propres appareils pour passer au crible des éléments contradictoires et ambigus pour assembler les éléments est parfois frustrant mais fournit une compréhension plus complète du cadre sur lequel nous nous appuyons tous les jours).
Après beaucoup de lecture, voici ma compréhension:
Si un objet nécessite une finalisation, il pourrait occuper de la mémoire plus longtemps qu'il n'en a besoin - voici pourquoi: a) Tout type qui définit un destructeur (ou hérite d'un type qui définit un destructeur) est considéré comme finalisable; b) Lors de l'allocation (avant l'exécution du constructeur), un pointeur est placé dans la file d'attente de finalisation; c) Un objet finalisable nécessite normalement la récupération de 2 collections (au lieu de la norme 1); d) La suppression de la finalisation ne supprime pas un objet de la file d'attente de finalisation (comme indiqué par! FinalizeQueue dans SOS) Cette commande est trompeuse; Savoir quels objets se trouvent dans la file d'attente de finalisation (en soi) n'est pas utile; Il serait utile de savoir quels objets se trouvent dans la file d'attente de finalisation et nécessitent encore une finalisation (existe-t-il une commande pour cela?)
La suppression de la finalisation désactive un peu dans l'en-tête de l'objet indiquant au runtime qu'il n'a pas besoin d'avoir son Finalizer invoqué (n'a pas besoin de déplacer la file d'attente FReachable); Il reste dans la file d'attente de finalisation (et continue d'être signalé par! FinalizeQueue dans SOS)
Les classes DataTable, DataSet, DataView sont toutes enracinées dans MarshalByValueComponent, un objet finalisable qui peut (potentiellement) gérer des ressources non gérées
4 (nouvelles références):
Réponse originale:
Il y a beaucoup de réponses trompeuses et généralement très pauvres à ce sujet - toute personne qui a atterri ici devrait ignorer le bruit et lire attentivement les références ci-dessous.
Sans aucun doute, Dispose doit être appelé sur tous les objets Finalizable.
Les DataTables sont finalisables.
Calling Dispose accélère considérablement la récupération de mémoire.
MarshalByValueComponent appelle GC.SuppressFinalize (this) dans son Dispose () - ignorer cela signifie avoir à attendre des dizaines sinon des centaines de collections Gen0 avant que la mémoire ne soit récupérée:
Prenez-le de quelqu'un qui a vu des centaines de Mo de DataTables non référencés dans Gen2: cela est extrêmement important et complètement ignoré par les réponses sur ce fil.
Références:
1 - http://msdn.microsoft.com/en-us/library/ms973837.aspx
2 - http://vineetgupta.spaces.live.com/blog/cns!8DE4BDC896BEE1AD!1104.entry http://www.dotnetfunda.com/articles/article524-net-best-practice-no-2-improve-garbage -collector-performance-using-finalizedispose-pattern.aspx
3 - http://codeidol.com/csharp/net-framework/Inside-the-CLR/Automatic-Memory-Management/
la source
TableAdapter
s?Vous devez supposer qu'il fait quelque chose d'utile et appeler Dispose même s'il ne fait rien dans le courant. Dans les incarnations de NET Framework, rien ne garantit qu'il en sera ainsi dans les futures versions, ce qui entraînera une utilisation inefficace des ressources.
la source
DataTable
n'est pas scellé - ce n'est pas grave lorsque vous le faitesnew DataTable
, mais assez important lorsque vous prenez unDataTable
comme argument ou à la suite d'un appel de méthode.Même si l'objet n'a pas de ressources non gérées, la suppression peut aider le GC en cassant les graphiques des objets. En général, si l'objet implémente IDisposable, Dispose () doit être appelé.
Que Dispose () fasse réellement quelque chose ou non dépend de la classe donnée. Dans le cas de DataSet, l'implémentation Dispose () est héritée de MarshalByValueComponent. Il se retire du conteneur et appelle l'événement Disposed. Le code source est ci-dessous (démonté avec .NET Reflector):
la source
Créez-vous vous-même les DataTables? Parce que l'itération à travers les enfants de n'importe quel objet (comme dans DataSet.Tables) n'est généralement pas nécessaire, car c'est le travail du parent de supprimer tous ses membres enfants.
En règle générale, la règle est la suivante: si vous l'avez créé et qu'il implémente IDisposable, supprimez-le. Si vous ne l'avez PAS créé, ne le supprimez PAS, c'est le travail de l'objet parent. Mais chaque objet peut avoir des règles spéciales, consultez la documentation.
Pour .net 3.5, il dit explicitement "Éliminez-le lorsque vous ne l'utilisez plus", c'est donc ce que je ferais.
la source
J'appelle dispose chaque fois qu'un objet implémente IDisposeable. C'est là pour une raison.
Les ensembles de données peuvent être de gros porcs de mémoire. Le plus tôt ils peuvent être marqués pour le nettoyage, mieux c'est.
mettre à jour
Cela fait 5 ans que j'ai répondu à cette question. Je suis toujours d'accord avec ma réponse. S'il existe une méthode dispose, elle doit être appelée lorsque vous avez terminé avec l'objet. L'interface IDispose a été implémentée pour une raison.
la source
Si votre intention ou le contexte de cette question est vraiment un ramasse-miettes, vous pouvez définir explicitement les ensembles de données et les tables de données sur null ou utiliser le mot clé using et les laisser hors de portée. Éliminer ne fait pas grand chose comme Tetraneutron l'a dit plus tôt. GC collectera les objets de l'ensemble de données qui ne sont plus référencés ainsi que ceux qui sont hors de portée.
Je souhaite vraiment que les gens forcés à voter aient réellement écrit un commentaire avant de voter contre la réponse.
la source
Les ensembles de données implémentent IDisposable à fond MarshalByValueComponent, qui implémente IDisposable. Étant donné que les ensembles de données sont gérés, il n'y a aucun avantage réel à appeler Dispose.
la source
Essayez d'utiliser la fonction Clear (). Cela fonctionne très bien pour moi pour l'élimination.
la source
la source