Entsorgung eine singleton-Instanz (C#)
Wenn ein singleton implementiert IDisposable, was ist die richtige Art und Weise der Entsorgung und re-erstellen einer Instanz? Eine Möglichkeit wäre, halten _disposed Flagge und überprüfen Sie es in die Instanz-Eigenschaft, aber ich bin nicht sicher, es ist der richtige Weg, dies zu tun. Ein einfaches Beispiel:
public sealed class Singleton: IDisposable
{
private static Singleton _instance;
private object _lock;
private UnmanagedResource _unmanaged;
private bool _disposed;
private Singleton()
{
_unmanaged = new UnmanagedResource();
_disposed = false;
_lock = new object();
}
public UnmanagedResource Unmanaged { get { return _unmanaged; } }
public static Singleton Instance
{
get
{
if (_instance == null || _disposed)
{
lock (_lock)
{
if (_instance == null || _disposed)
{
_instance = new Singleton();
}
}
}
return _instance;
}
}
public void Dispose()
{
_disposed = true;
try
{
_unmanaged.Dispose();
}
finally
{
GC.SuppressFinalize(this);
}
}
}
So, dass code mag dies möglich ist (obwohl, ja, ich Stimme zu, es Art von Niederlagen der Zweck des habens ein Singleton):
Singleton.Instance.Dispose();
Singleton.Instance.Unmanaged.UseResource(); //Unmanaged shouldn't be null.
HINWEIS: gibt Es keine Notwendigkeit zu betonen Inkompatibilität zwischen Singleton-und IDisposable, ich verstehe es. Ich brauche Dispose-Methode nicht verwaltete Ressourcen frei, wenn ApppDomain entlädt. Wenn Sie ein problem mit dieser Klasse aufgerufen wird, Singleton, ich kann es umbenennen, LoadBalancer statt. Die Frage bleibt dennoch die gleiche. Diese LoadBalancer werden muss, Einweg, weil es die Instanz, die niemandem gehört, sondern sollten ordnungsgemäß entsorgt werden.
sichern UnamanagedResource und bieten load-balancing für die Nutzung dieser resouse
InformationsquelleAutor kateroh | 2011-06-03
Du musst angemeldet sein, um einen Kommentar abzugeben.
wenn Sie brauchen, um zu ersetzen Sie die Instanz von singleton ist, sollten Sie sich Gedanken über Ihr design.
wenn Sie WIRKLICH denken, Sie sollten dies tun, würde ich vorschlagen, für die Verwendung von 2 Objekten ...
einem singleton-Objekt, das als proxy fungiert, und ein echtes singleton (end of lifetime == Ende des Prozesses)
dieses Objekt Bedarf der öffentlichen Mitglieder für alles, was Ihre singleton ist in der Lage, und ein privates Mitglied, das die tatsächlichen Implementierung-Objekt. alle anderen Mitglieder Umleitung zu Mitgliedern der Umsetzung.
das zweite Objekt ist die Wegwerf-Objekt, das ersetzt werden kann. stellen Sie sicher, dass nur das singleton-Objekt wird immer über einen Verweis auf... diese Weise ist es egal, ob jeder Verbraucher-Objekt hält eine Referenz auf die singleton-das würde verhindern, dass Sie ersetzen das Objekt ..., das ref wird nur Punkt-zu-proxy -
InformationsquelleAutor DarkSquirrel42
Singleton-und Wegwerf-Objekte sind weitgehend unvereinbar Konzepte
Singletons sind generell lebendig für die Lebensdauer eines Prozesses /
AppDomain
. Wenn Sie finden, sich selbst zu wollenDispose
Sie dann müssen Sie wahrscheinlich überarbeiten Sie Ihre Lösung ein bisschen.Wenn das problem rund um die Verfügbarmachung von Ressourcen, die während einer
AppDomain
entladen, dann legen Sie die Verantwortung der Befreiung der Ressource mit dem gleichen Objekt verantwortlich für die Verwaltung der Lebensdauer derAppDomain
. Binden Sie dann diese Ressource in derSingleton
ohne die ImplementierungIDisposable
. Das wird richtig trennen den Anliegen des Szenarios ist.Hinzugefügt einige weitere details, wie die Trennung von diesem aus besser
danke, DarkSquirrel42 schlug vor, diese frühere
Warum nicht einen finalizer implementieren, reinigt diese nicht verwaltete Ressourcen? Finalizer aufgerufen werden, auf AppDomain-Kündigung in den meisten Fällen. In den seltenen gezwungen bricht ab, können Sie verlassen sich immer noch auf kritische Finalizer über
CriticalFinalizerObject
.InformationsquelleAutor JaredPar
Ich bin nicht zu sehen, wie dies funktionieren wird. Betrachten Sie diese hypothetische Anwendungsfall:
Wie wollen Sie guard gegen mehrere threads ausführen dieses Codes gleichzeitig? Einen thread nennen könnte
Dispose
während die anderen noch versucht, die gleiche Instanz. Versuchen, eine Kraft, eine API mit recycling-Semantik in der singleton-Konzept ist wie das versuchen zu passen, ein square peg in a Runde halten.Durch die Art und Weise, es ist tangential nennenswerten Probleme. Die
Instance
Eigenschaft ist nicht thread-safe. Zumindest markieren Sie_instance
alsvolatile
. Und das geht nur, wenn Sie wurden mit der kanonischen Implementierung des Musters. Sie werden nie in der Lage, um das Muster sicher, da man auch verwenden, die_disposed
Flagge als zusätzliche Kriterien in die Prüfung ein. Ich persönlich würde nur noch Schrott das double-checked-locking-Muster insgesamt.Keine Menge an code in der
Dispose
Methode Korrektur der nicht-lock code in dasInstance
Eigenschaft. Auch wenn Sie Hinzugefügtvolatile
sowohl_instance
und_disposed
Sie immer noch nicht funktionieren.InformationsquelleAutor Brian Gideon
Vielleicht Frage ich ja eine dumme Frage, aber warum würde Sie entsorgen möchten ein Singleton nur um eine neue zu erstellen? Ist das nicht der Zweck nur eine Instanz zu haben....
Könnte dies ein design-Problem bin ich mir nicht bewusst. Vielleicht ist der "richtige Weg" ist in diesem Fall neu zu bewerten, was Sie brauchen, Ihren code zu tun ist und was Muster bekommt Sie es.
Vielleicht hat er das schreiben von unit-tests?
InformationsquelleAutor PSU_Kardi