Die Verwendung von Dispose für ein Singleton zu Bereinigung Ressourcen
Die Frage, die ich habe vielleicht mehr zu tun mit der Semantik, als mit der tatsächlichen Verwendung von IDisposable
. Ich arbeite an der Umsetzung eines singleton-Klasse, die ist verantwortlich für die Verwaltung einer Datenbank-Instanz ist, dass während der Ausführung der Anwendung. Wenn die Anwendung geschlossen wird diese Datenbank gelöscht werden sollen.
Nun habe ich dieses löschen erfolgt durch eine Cleanup()
- Methode des singleton, die die Anwendung aufruft, wenn Sie geschlossen wird. Als ich war das schreiben der Dokumentation für Cleanup()
es fiel mir auf, dass ich beschreiben, was eine Dispose()
Methode sollte verwendet werden, für z.B. Reinigungs-Ressourcen. Ich hatte ursprünglich nicht implementiert IDisposable
da es schien, der Platz in meinem singleton, weil ich nicht wollen, etwas zu entsorgen das singleton selbst. Es ist derzeit nicht, aber in der Zukunft könnte ein Grund dafür sein, dass diese Cleanup()
genannt werden könnte, sondern das singleton sollte müssen immer noch existieren. Ich denke, ich kann zählen GC.SuppressFinalize(this);
in der Dispose-Methode machen dies möglich.
Meine Frage ist daher, multi-geteilt:
1) Ist die Umsetzung IDisposable
auf ein singleton ist grundsätzlich eine schlechte Idee?
2) Bin ich gerade mischen Semantik hier durch eine Cleanup()
statt einer Dispose()
- und da bin ich der Entsorgung Ressourcen, die ich wirklich verwenden sollte entsorgen?
3) Wird die Umsetzung von "Dispose ()" mit GC.SuppressFinalize(this);
es so machen, mein singleton ist eigentlich nicht zerstört in dem Fall möchte ich es zu Leben, nachdem ein Aufruf zum clean-up der Datenbank.
InformationsquelleAutor Craig Suchanec | 2010-05-28
Du musst angemeldet sein, um einen Kommentar abzugeben.
Kurz gesagt, wenn Sie ein singleton, und Sie rufen Sie dispose auf. Jedes mal, dass ein Objekt versucht, nach diesem, werden unter Verwendung eines Objekts in einem entsorgt Zustand.
Nun setzen Sie in-und Entsorgung des Objektes nach der Anwendung ist, ist nicht unbedingt schlecht. Sie müssen vorsichtig sein, obwohl, wenn Sie es nennen. Wenn Sie wirklich besorgt mit den Aufräumarbeiten und man muss nur noch eine Referenz auf Sie, Sie können die clean-up-code in die finalizer-Objekte
~YourClass
so wird es nur aufgerufen werden, mit .Net ist sicher, es ist nicht mehr erforderlich (wenn die Anwendung geschlossen wird, wenn es ist ein echtes singleton).Ja, das ist nur Semantik. Entsorgen ist der standard für das zeigen, es gibt Dinge, die müssen geklärt werden, nachdem das Programm fertig ist mit dem Objekt.
Nicht was dies bedeutet ist, dass, wenn Sie die dispose-Methode aufrufen, wird der Garbage Collector wird nicht rufen Sie das Objekt benutzerdefinierte finalizer.
.Dispose()
auf Anwendungen Exitpoint?InformationsquelleAutor kemiller2002
Implementierung von IDisposable für singleton könnte gute Idee, wenn Sie der Verwendung von CAS-techinque statt sperren zum erstellen einer singleton. So etwas wie dieses.
Wir erstellt ein temporäres Objekt und versucht, Atomare Compare-and-Swap -, so müssen wir entsorgen dieses temporäre Objekt, wenn es impletents IDisposable und es war nicht geschrieben Instanz Lage.
Es könnte gut sein, um sperren zu vermeiden, aber auch, es ist ein bisschen overhead, wenn einige schwere Logik wird verwendet, um eine singleton-Instanz, die in Ihrem Konstruktor.
Wenn Sie nicht möchten, dass andere code-cleanup oder entsorgen Sie Ihr Objekt gerade nicht bieten keine Chance für diese. Jedoch, es könnte gute Idee, irgendeine Art von reset () - Methode auf, damit singleton zu erstellen, selbst wenn, sagen wir, Sie verwenden einen lazy init. So etwas wie dieses:
InformationsquelleAutor Andrey Taptunov
Ich Stimme mit Kevin, die Antwort, aber möchte noch etwas hinzufügen. Ich bin ein wenig verwirrt über deine Aussage:
Meinst du das wirklich gelöscht? Wie zerstört? Sprechen Sie über eine echte (SQL -) Datenbank?
Müssen Sie verstehen, dass, selbst wenn Sie Ihre clean-up-code in einen finalizer, oder in die Application_End-Ereignis (ASP.NET) es gibt keine Möglichkeit sicherzustellen, können Sie diese aufgerufen werden. Der Prozess kann beendet werden, oder der computer an Leistung verliert. Es scheint mehr vernünftig zum löschen der Datenbank beim starten der Anwendung, oder zumindest einen fallback-Mechanismus beim Start mit etwas Aufräumen.
Während der finalizer wäre ein guter Ort, um Aufräumarbeiten im Umgang mit Ressourcen, in Ihrem Fall sprechen wir über einen Anwendung Ressource. Was ich durch dieses bedeute, ist, dass die Ressource nicht vielleicht gebunden, auf ein einziges Objekt (singleton), sondern ist Teil der gesamten Anwendung. Dies kann ein bisschen eine abstrakte Diskussion, und es ist vielleicht mehr eine Frage der Ansicht.
Was ich bin versucht zu sagen, dass, wenn Sie sehen, dass die Datenbank-Anwendung Ressource, die Sie haben, um Ihre Initialisierung und cleanup nicht an ein Objekt gebunden, sondern an die Anwendung. In einem ASP.NET Anwendung dieses wäre Application_Start und Application_End (global.asax). In einer Windows Forms-Anwendung, dies würde sein Programm.Main.
Immer noch, wenn mit diesen Mechanismen über Finalizer, Sie haben keine Gewissheit, dass Ihre clean-up-code ausgeführt wird.
InformationsquelleAutor Steven