À l'aide de Disposer sur un Singleton pour nettoyer les Ressources
La question que j'ai peut-être plus à voir avec la sémantique que l'utilisation réelle de IDisposable
. Je suis en train de travailler sur la mise en œuvre d'une classe singleton qui est en charge de la gestion d'une instance de base de données qui est créé lors de l'exécution de l'application. Lorsque l'application se ferme cette base de données devrait être supprimé.
Droit maintenant, j'ai ce supprimer gérée par un Cleanup()
méthode du singleton que l'application appelle quand il est en cours de fermeture. Comme je l'écrivais la documentation pour Cleanup()
il m'a semblé que j'avais décrit ce qu'est un Dispose()
méthode doit être utilisée pour exemple le nettoyage des ressources. J'avais initialement pas mis en œuvre IDisposable
parce qu'il semblait sortir de la place dans mon singleton, parce que je ne voulais rien à jeter le singleton lui-même. Il n'y a pas actuellement, mais à l'avenir, pourrait être une raison pour que cette Cleanup()
pourrait être appelé, mais le singleton devrait aurez besoin d'exister encore. Je pense que je peux inclure GC.SuppressFinalize(this);
dans la méthode dispose pour rendre cela possible.
Ma question est donc multi-parted:
1) Est la mise en œuvre de IDisposable
sur un singleton fondamentalement une mauvaise idée?
2) Suis-je juste le mélange de la sémantique ici par le fait d'avoir un Cleanup()
au lieu d'un Dispose()
et depuis que je suis disposer de ressources que j'ai vraiment devrait utiliser un aliéner?
3) la mise en œuvre de la "Dispose ()" avec GC.SuppressFinalize(this);
faire en sorte que mon singleton n'est pas réellement détruits dans le cas où je veux vivre après un appel à un nettoyage de la base de données.
OriginalL'auteur Craig Suchanec | 2010-05-28
Vous devez vous connecter pour publier un commentaire.
En bref, si vous avez un singleton et vous appelez dispose. Tout le temps que tout objet essaie de l'utiliser après ça, va être l'aide d'un objet dans un éliminées de l'état.
Maintenant de le mettre, et l'élimination de l'objet après l'application se fait avec elle, n'est pas nécessairement mauvais. Vous ne devez être prudent lorsque vous l'appelez. Si vous êtes vraiment intéressé à le nettoyage et vous n'avez qu'une seule référence à elle, vous pouvez mettre le nettoyage du code dans le finaliseur des objets
~YourClass
de cette façon, il ne sera appelée .Net est sûr qu'il n'est plus nécessaire (lorsque l'application se ferme, si c'est un vrai singleton).Oui, c'est juste de la sémantique. Disposer est la norme pour montrer il y a des choses qui doivent être effacée après le programme est terminé avec l'objet.
Pas ce que cela signifie est que lorsque vous appelez la méthode dispose, le Garbage Collector ne vais pas l'appeler de l'objet personnalisé finalizer.
.Dispose()
sur les Applications Exitpoint?OriginalL'auteur kemiller2002
La mise en œuvre de IDisposable pour singleton pourrait être une bonne idée si vous utilisez un TAS techinque au lieu de serrures pour créer un singleton. Quelque chose comme cela.
Nous avons créé un objet temporaire et essayé atomique Compare-and-Swap nous avons donc besoin de disposer de cet objet temporaire si elle impletents IDisposable et il n'était pas écrit à l'instance de l'emplacement.
Il pourrait être bon d'éviter les verrous, mais aussi c'est un peu frais généraux si certains lourd logique est utilisé pour créer un singleton instance dans son constructeur.
Si vous ne voulez pas d'un autre code de nettoyage ou de céder votre objet, il suffit de ne pas fournir toute occasion. Cependant, il pourrait être une bonne idée de fournir une sorte de méthode reset() pour permettre singleton pour recréer lui-même si, disons par exemple, vous utilisez un paresseux init. Quelque chose comme ceci:
OriginalL'auteur Andrey Taptunov
Je suis d'accord avec Kevin réponse, mais comme pour ajouter quelque chose à cela. Je suis un peu confus au sujet de votre déclaration:
Pensez-vous vraiment dire supprimé? Comme dans détruits? Parlez-vous une réel (SQL) de la base de données?
Vous devez comprendre que même si vous mettez votre propre code dans un finaliseur, ou dans le Application_End événement (ASP.NET) il n'y a aucun moyen que vous pouvez garantir, ils sont appelés. Le processus peut être interrompu, ou de l'ordinateur perd de la puissance. Il semble plus raisonnable de supprimer la base de données de démarrage de l'application, ou au moins avoir un mécanisme de secours au démarrage avec un peu de ménage.
Tandis que le finaliseur serait un bon endroit pour mettre de nettoyage lorsque vous traitez avec des ressources, dans votre cas, nous parlons d'un ressource d'application. Ce que je veux dire par là, c'est que la ressource n'est pas peut-être lié à un seul objet (votre singleton) mais fait partie de l'ensemble de l'application. Cela peut être un peu un résumé de la discussion, et c'est peut-être plus une question de point de vue.
Ce que je suis en train de dire que quand vous voyez que la base de données en tant que ressource d'application, vous devrez avoir votre initialisation et de nettoyage qui n'est pas lié à un objet, mais à l'application. Dans un ASP.NET application ce serait Application_Start et Application_End (à l'échelle mondiale.asax). Dans une application Windows Forms, ce serait au Programme.Principal.
Encore, lors de l'utilisation de ces mécanismes sur les finaliseurs, vous n'avez aucune certitude que votre propre code à exécuter.
OriginalL'auteur Steven