Quel est le point de raisons dispose(bool disposing) dans .NET?
Si j'écris une classe en C# qui implémente IDisposable, pourquoi n'est-ce pas, c'est suffisant pour moi de simplement mettre en œuvre
public void Dispose(){ ... }
à la poignée de libérer toutes les ressources non managées?
Est
protected virtual void Dispose(bool disposing){ ... }
toujours nécessaire, parfois nécessaire, ou tout autre chose?
- Dans ma classe, je n'ai que des ressources non managées qui a besoin d'être nettoyé et je me suis mise en œuvre de IDisposable avec protected virtual void dispose(bool disposing) que de l'analyse statique des forces pour le faire. Dans mon cas, le "élimination" paramètre n'a pas d'utilisation que je voudrais Finaliseur et d'en Disposer à faire la même chose.
Vous devez vous connecter pour publier un commentaire.
Il n'est pas strictement nécessaire. Il fait partie de la recommandé Jetables modèle. Si vous n'avez pas lu la Conception du Cadre des lignes Directrices sur ce (9.3 dans la première édition, n'ont pas la deuxième édition pratique désolé) alors vous devriez. Essayez ce lien.
Il est utile de distinguer entre jetables de nettoyage et finalisable garbage-collection-est-dénigrer-moi.
Vous n'avez pas à le faire de cette façon, mais vous devez la lire et de comprendre pourquoi il est recommandé, avant de l'écarter comme inutile.
Le modèle complet, y compris un outil de finalisation, l'introduction d'une nouvelle méthode virtuelle et "d'étanchéité" de l'original de la méthode dispose est très à usage général, couvrant toutes les bases.
Sauf si vous avez direct poignées sur les ressources non managées (qui devrait être presque jamais) vous n'avez pas besoin d'un outil de finalisation.
Si vous scellez votre classe (et de mon point de vue sur l'étanchéité des classes dans la mesure du possible sont probablement bien connue maintenant - la conception de l'héritage ou de l'interdire) il n'y a aucun point dans l'introduction d'une méthode virtuelle.
Je ne me souviens pas la dernière fois que j'ai mis en place
IDisposable
dans un "complexe" de manière vs de le faire de la manière la plus évidente, par exempleUne chose à noter est que si vous allez pour vraiment robuste code, vous devrait assurez-vous que vous n'essayez pas de faire quoi que ce soit après que vous avez été éliminés, et de le jeter
ObjectDisposedException
le cas échéant. C'est un bon conseil pour les bibliothèques de classes qui seront utilisées par les développeurs du monde entier, mais c'est beaucoup de travail pour très peu de gain si c'est simplement une classe au sein de votre propre espace de travail.Il y a un peu de biais dans les MSFT docs sur le modèle jetable. Il y a deux raisons pour lesquelles vous devriez mettre en œuvre IDisposable:
Le cas 1 est assez commun dans la plupart des code. Le cas 2 est assez commun dans le code de Microsoft à l'écrit, ils ont été ceux qui ont écrit la gestion de wrappers autour des ressources non managées, ceux qui ont besoin de finalisation. Mais il doit être très rare dans votre code. Après tout, vous avez toutes ces belles .NET les classes pour faire le sale boulot pour vous. Vous avez juste à appeler leur Dispose() méthodes.
Seul cas 2 exige que les jetables modèle. Microsoft a besoin de beaucoup l'utiliser. Vous aurez juste besoin d'une simple Dispose() la plupart du temps.
En plus des autres grandes réponses, vous pouvez consulter ces articles:
La méthode supplémentaire avec le bool disposing sorti d'un cadre de lignes directrices de conception quelque part. C'est tout simplement un modèle pour permettre à votre classe d'avoir la méthode dispose pouvoir être appelé plusieurs fois sans lancer une exception. Il n'est pas absolument nécessaire. Techniquement, vous pourriez le faire dans la méthode dispose.
Juste pour élargir sur ce que les autres ont dit: c'est pas juste que vous n'avez pas besoin le "complexe d'en disposer", c'est que vous ne veux pas qu'il, pour des raisons de performances.
Si vous allez le complexe de disposer de route, et de mettre en œuvre un outil de finalisation, et puis l'oublier explicitement supprimer votre objet, votre objet (et tout ce à quoi il fait référence) de survivre à un extra GC génération d'avant, c'est vraiment disposé (puisqu'elle a pour traîner une fois de plus pour le CLR pour appeler l'outil de finalisation). Cette juste cause plus de pression de mémoire que vous n'avez pas besoin. En outre, l'appel de la finaliseur sur tout un tas d'objets a un non-trivial coût.
Afin d'éviter, à moins que vous (ou vos types dérivés) ont des ressources non managées.
Oh, et pendant que nous sommes dans la zone: les méthodes de votre classe permettant de gérer les événements des autres doivent être "en sécurité" en face de l'être appelée une fois que votre classe a été disposé. La plus simple est de simplement effectuer un no-op si la classe est éliminé. Voir http://blogs.msdn.com/ericlippert/archive/2009/04/29/events-and-races.aspx
Une chose qu'il vous donne est la capacité à travailler en Dispose() non reliés à la mise au point, et encore nettoyer des ressources non managées.
Faire rien à un objet géré autre que 'vous' dans un finaliseur est extrêmement... imprévisible. La plupart de ceci est dû au fait que votre finaliseurs sera appelé dans la phase 2 de l'arrêt de votre domaine d'application dans un non-déterministe manière - de sorte que lorsque votre finaliseur est appelé, il est extrêmement probable que les objets que vous avez encore des références à ont déjà été finalisés.
Expédition à la fois le Jeter et finalizer appels à la même méthode vous permet de partager votre code d'arrêt, tandis que le paramètre booléen vous permet de passer le réussi nettoyage si vous en avez.
Aussi, la quasi-ness de la méthode fournit un moyen facile pour les héritiers d'ajouter leur propre code de nettoyage, avec moins de risques de par inadvertance, en n'appelant pas la vôtre.
Si une classe implémente
IDisposable.Dispose()
et une classe dérivée doit ajouter de la logique supplémentaire, cette classe doit exposer une sorte deDispose
méthode de la classe dérivée peut de la chaîne d'. Depuis, certains cours pourront mettre en œuvreIDisposable.Dispose()
sans avoir un publicDispose()
méthode, il est utile d'avoir une méthode virtuelle qui seraprotected
dans toutes les implémentations deIDisposable
indépendamment du fait qu'ils ont un publicDispose
méthode ou pas. Dans la plupart des cas, labool
argument n'est pas vraiment utile, mais doit être considéré comme un argument pour faire de laprotected virtual Dispose(bool)
avoir une signature différente de la peut-être-ou-peut-être-pas-publicDispose()
.Classes qui n'utilise pas
protected virtual Dispose(bool)
exigera que les classes dérivées à gérer leur logique de nettoyage, d'une manière qui diffère de la convention. Certains langages comme C++/CLI qui ne sont plus équipés d'étendreIDisposable
implémentations qui suivent cette convention peut être impossible de dériver des classes de non-mise en œuvre standard.