Frage

Es ist dieses DB-Verbindung-ähnliche Objekt, das meine Web-Anwendung benötigen. Es ist ziemlich langsam zu schaffen und wird selten verwendet werden, so dass ich nur um eine einzelne Instanz halten mag. Wenn mehrere Anfragen es zur gleichen Zeit benötigen, werden sie das Objekt lock() und ihren Zugang serialisiert werden soll.

Um die Dinge mehr Spaß das Objekt ein IDisposable und kann geschlossen werden. Natürlich werde ich das Schreiben von Code vermeiden, dass es geschlossen wird, aber ... Sie wissen schon ... sicher ist sicher, nicht wahr?

So würde der naive Ansatz, es zu implementieren etwas wie folgt aus:

private static DBClass _Instance;
private static object _DBLock = new object();

public DBClass GetDB()
{
    if ( _Instance == null )
        lock (_DBLock )
            if ( _Instance == null )
                _Instance = CreateInstance();
    lock (_Instance)
        if ( _Instance.Disposed )
            _Instance = CreateInstance();
    return _Instance;
}

Es wird dann wie verwendet werden:

lock (var Conn = Global.GetDB() )
{
    // Use Conn here.
}

Dies wird wahrscheinlich die meiste Zeit arbeiten, aber ich sehe eine Öffnung, die ausgenutzt werden könnte - wenn zwei Threads dies zugleich nennen sie die gleiche Instanz zur gleichen Zeit, und dann konnte man es noch Dispose() vor der andere erwirbt eine lock() darauf. So - später Code fehlschlägt. Überprüfen auf Disposed an jedem Ort, dass es auch umständlich scheint verwendet. In der Tat, lock()ing scheint es zu umständlich, aber das Beispiel ist nicht von Natur aus Thread-sicher so gibt es nichts ich dagegen tun kann.

Wie würden Sie implementieren das?

War es hilfreich?

Lösung

Für den Anfang würde ich doppelt überprüft Verriegelung zu vermeiden vorschlagen. Es ist sehr einfach, es falsch zu bekommen -., Wie Sie in diesem Fall getan haben, indem sie nicht die Variable volatilen machen

Da Sie nicht wollen wirklich das Objekt verfügt, gibt es keinen Grund es nicht zu wickeln in etwas, das die gleichen API implementiert, aber ohne Entsorgung auszusetzen? Auf diese Weise können Sie auch die Verriegelung einkapseln, möglicherweise, je nachdem, wie Sie tatsächlich das Objekt verwenden. Ein anderer Weg, dies zu tun, wäre eine API in Bezug auf Action<DBClass> aussetzen -. Sie passieren in der Aktion, die Sie mit dem Objekt nehmen möchten, und die Helfer kümmert sich um die Instanz zu erstellen und Verriegelung in geeigneter Weise

Ein letzter Punkt: all dies fühlt sich etwas heikel in Bezug auf die Überprüfbarkeit. Ich weiß nicht, ob Sie ein Fan von Unit-Tests sind usw., aber Singletons oft machen das Leben etwas umständlich für den Test.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top