Frage

Ich habe versucht jemand, warum Datenbankverbindungen implementieren IDisposable, zu erklären, als ich merkte, ich weiß nicht wirklich, was „Öffnen eine Verbindung“ eigentlich bedeuten.
Also meine Frage ist - was praktisch tut c # tun, wenn es eine Verbindung öffnet?

Danke.

War es hilfreich?

Lösung

Es gibt tatsächlich zwei bei der Umsetzung eine Verbindung beteiligten Klassen (eigentlich mehr, aber ich bin zu vereinfachen).

Eine davon ist die IDbConnection Implementierung (SQLConnection, NpgsqlConnection, OracleConnection, etc.), dass Sie in Ihrem Code verwenden. Die andere sind ein „echtes“ Verbindungsobjekt, das zur Montage intern ist, und der Code nicht sichtbar. Wir werden jetzt dieses „RealConnection“ nennen, obwohl sein eigentlicher Name unterscheidet sich mit verschiedenen Implementierungen (zum Beispiel in Npgsql, was der Fall ist, wo ich am meisten vertraut mit der Umsetzung bin, wird die Klasse genannt NpgsqlConnector).

Wenn Sie Ihre IDbConnection erstellen, es hat keinen RealConnection. Jeder Versuch, etwas zu tun mit der Datenbank fehl. Wenn Sie es Open() dann passiert folgendes:

  1. Wenn Pooling aktiviert ist, und es gibt eine RealConnection im Pool, deque es und es die RealConnection für die IDbConnection machen.
  2. Wenn Pooling aktiviert ist, und die Gesamtzahl der RealConnection Objekte in Existenz ist größer als die maximale Größe, eine Ausnahme aus.
  3. Andernfalls eine neue RealConnection erstellen. Initialise es, die irgendeine Art von Netzwerkverbindung (z TCP / IP) oder Datei-Handle (für so etwas wie Access) öffnen beinhalten wird, gehen Sie durch die Protokoll-Datenbank für Handshake (variiert je nach Datenbanktyp) und die Verbindung autorisieren. Dies wird dann der RealConnection für die IDbConnection.

Operationen durch auf dem IDbConnection geführt werden, in dem Betrieb einge die RealConnection tut auf seiner Netzwerkverbindung (oder was auch immer). Die Ergebnisse sind in Objekte gedreht IDataReader Umsetzung und so weiter, um eine einheitliche Schnittstelle für die Programmierung zu geben.

Wenn ein IDataReader mit CommandBehavior.CloseConnection erstellt wurde, dann ist das Datareader erhält „Eigentum“ des RealConnection.

Wenn Sie anrufen Close() dann eine der folgenden Ereignisse eintritt:

  1. Wenn die Bündelung und wenn der Pool nicht voll ist, dann wird das Objekt in der Warteschlange für den Einsatz setzt mit späteren Operationen.
  2. Andernfalls ist die RealConnection durchführen werden alle protokolldefinierten Verfahren zum Beenden der Verbindung (Signalisierung an die Datenbank, dass die Verbindung zum Herunterfahren wird) und schließt die Netzwerkverbindung usw. Das Objekt kann dann der Umfang herausfallen und verfügbar werden für die Garbage collection.

Die Ausnahme wäre, wenn der CommandBehavior.CloseConnection Fall geschehen ist, in diesem Fall ist es die Close() oder Dispose() auf dem IDataReader aufgerufen wird, dass Trigger dies.

Wenn Sie rufen Dispose() dann das gleiche passiert wie pro Close(). Der Unterschied ist, dass Dispose() wird als „clean-up“ und kann mit using arbeiten, während Close() könnte durch eine spätere Open() in der Mitte der Lebensdauer und anschließend verwendet werden.

Durch die Verwendung des RealConnection Objekts und der Tatsache, dass sie vereinigt sind, das Öffnen und Schließen von Verbindungen ändert etwas relativ schwer zu relativ leicht. Daher anstatt es wichtig ist, Verbindungen für eine lange Zeit offen zu halten, den Aufwand zu öffnen, sie zu vermeiden, wird es wichtig, sie für so kurze Zeit wie möglich offen zu halten, da die RealConnection beschäftigt sich mit dem Aufwand für Sie, und je mehr schnell Sie sie verwenden, desto effizienter die gepoolten Verbindungen zwischen den Anwendungen gemeinsam genutzt bekommen.

Beachten Sie auch, dass es okay ist ein Dispose() IDbConnection, dass Sie bereits Close() aufgerufen haben (es ist eine Regel, dass es immer sicher sein sollte Dispose(), was auch immer der Staat zu nennen, in der Tat, auch wenn es bereits genannt wurde). Daher, wenn Sie manuell Close() aufrufen würde, würde es immer noch gut sein, die Verbindung in einem using habenBlock, Fälle zu fangen, wo Ausnahmen vor dem Aufruf von Close() passieren. Die einzige Ausnahme ist, wo Sie die Verbindung tatsächlich wollen, offen bleiben; sagen Sie ein IDataReader mit CommandBehavior.CloseConnection erstellt wurden, zurückkehren, in dem Fall, dass Sie die IDbConnection nicht entsorgen, aber entsorgen die Leser.

ausfällt Sie die Verbindung verfügen, dann ist die RealConnection nicht an den Pool für die Wiederverwendung zurückgegeben werden, oder seine Abschaltverfahren gehen. Entweder ist der Pool wird seine Grenze erreicht, oder die Anzahl der zugrunde liegenden Verbindungen bis zu dem Punkt erhöhen die Leistung der Beschädigung und Blockierung mehr von geschaffen. Schließlich wird die finaliser auf RealConnection genannt werden kann und führen zu dieser befestigt ist, aber Finalisierung nur reduziert den Schaden und kann nicht auf sie verlassen werden. (Die IDbConnection braucht keine finaliser, wie es die RealConnection ist, dass die nicht verwaltete Ressource hält und / oder Bedürfnisse der Abschaltung zu tun).

Es ist auch anzunehmen, dass es eine andere Anforderung ist für die Entsorgung einzigartig für die Umsetzung der IDbConnection darüber hinaus, und es sollte noch selbst entsorgt werden, wenn die oben genannten Leitungen analysieren Sie es nicht nötig, zu glauben (die Ausnahme ist, wenn CommandBehavior.CloseConnection leitet alle Entsorgungs Belastung für die IDataReader, aber dann ist es ebenso wichtig, dass die Leser zu entsorgen).

Andere Tipps

Gute Frage.

Aus meinem (etwas eingeschränkt Wissen) der „unter der Motorhaube“ Arbeits einer SQL-Verbindung, sind viele Schritte beteiligt ist, wie zum Beispiel:

Die Schritte unter der Haube

  1. Physikalische Buchse / Rohr geöffnet wird (gegeben Treiber, zB ODBC)
  2. Handshake mit SQL Server
  3. Verbindungszeichenfolge / Berechtigungsnachweise auf Anfrage
  4. Transaktions Scoping

Nicht zu erwähnen, Connection Pooling, glaube ich, gibt es eine Art von alogrithm beteiligt (wenn die Verbindungszeichenfolge übereinstimmt für einen bereits vorhandenen Pool, wird die Verbindung zum Pool hinzugefügt, ansonsten neu erstellt wird)

IDiposable

Im Hinblick auf die SQL-Verbindungen realisieren wir IDisposable so, dass, wenn wir dispose aufrufen (entweder über die using-Direktive oder explizit), wird die Verbindung wieder in den Verbindungspool platziert. Dies steht in krassem Gegensatz zu nur dem einfachen alten SQLConnection.close (.) - wie all dies tut, ist nah es vorübergehend, behält sich aber, dass die Verbindung zur späteren Verwendung

Von meinem Verständnis, .Close () schließt die Verbindung zur Datenbank, während .Dispose () ruft .Close () und und Veröffentlichungen nicht verwalteten Ressourcen.

Diese Punkte im Auge, zumindest aber es ist eine gute Praxis IDisposable umzusetzen.

Das Hinzufügen Antworten oben ... Der Schlüssel ist, dass auf „Öffnen der Verbindung“ Ressourcen zugewiesen werden, dass mehr als die Standard-Garbage-Collection wird zu erholen, nämlich eine offene Buchse / Rohr / IPC von Schokoladenriegel besorgt. Die Methode Dispose () reinigt diese nach oben.

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