Viele Leute denken, dass die Dispose()-Methode intern in der Close()-Methode aufgerufen wird, es gibt also keinen wesentlichen Unterschied! Tatsächlich ist diese Ansicht nicht sehr zutreffend.
Für einige Klassen gibt es zwar keinen wesentlichen Unterschied zwischen Close() und Dispose(), bei einigen Klassen ist dies jedoch nicht der Fall!
Schauen wir uns zunächst den Unterschied zwischen der Close()-Methode und der Dispose()-Methode von SqlConnection an, die wir am häufigsten verwenden:
Die Dispose()-Methode der SqlConnection-Klasse wird von der Component-Klasse geerbt. Der Quellcode lautet wie folgt:
public void Dispose() {
Dispose(true); //Eine Überladung von Dispose mit Parametern aufrufen
GC.SuppressFinalize(this); // Fordern Sie das System auf, den Finalizer des angegebenen Objekts nicht aufzurufen.
}
protected virtual void Dispose(bool disposing) {
if (entsorgen) {
lock(this) {
if (site != null && site.Container != null) {
site.Container.Remove(this);
}
if (events != null) {
EventHandler handler = (EventHandler)events[EventDisposed];
if (handler != null) handler(this, EventArgs.Empty);
}
}
}
}
Die Beschreibung der Close()-Methode der SqlConnection-Klasse in MSDN lautet wie folgt:
Schließen Sie die Verbindung zur Datenbank. Dies ist die bevorzugte Methode zum Schließen einer offenen Verbindung. Wenn die SqlConnection den Gültigkeitsbereich verlässt, wird sie nicht geschlossen. Weil
Daher muss die Verbindung explizit durch Aufrufen von Close oder Dispose geschlossen werden. Schließen und Entsorgen sind funktional gleichwertig. Wenn der Verbindungspoolwert
Pooling Wenn auf „true“ oder „yes“ gesetzt, wird die zugrunde liegende Verbindung an den Verbindungspool zurückgegeben. Wenn Pooling hingegen auf „false“ oder „no“ gesetzt ist, dann
Die zugrunde liegende Verbindung zum Server wird geschlossen.
Aus der Beschreibung geht hervor, dass die Close()-Methode und die Dispose()-Methode ähnlich sind. Tatsächlich sind sie nur in der Funktion zum Schließen der Verbindung gleichwertig.
() Quellcode der Methode:
public void Close() überschreiben
IntPtr hscp;
Bid.ScopeEnter(out hscp, "<sc.SqlConnection.Close|API> %d#" , ObjectID);
versuchen {
SqlStatistics-Statistiken = null;
RuntimeHelpers.PrepareConstrainedRegions();
versuchen {
#if DEBUG
object initialReliabilitySlotValue = Thread.GetData(TdsParser.ReliabilitySlot);
RuntimeHelpers.PrepareConstrainedRegions();
versuchen {
Thread.SetData(TdsParser.ReliabilitySlot, true);
#endif //DEBUG
Statistiken = SqlStatistics.StartTimer(Statistics);
// Die Sperre dient hier zum Schutz vor command.cancel/connection.close
Rennbedingung
// Die SqlInternalConnectionTds werden beim Schließen auf OpenBusy gesetzt, sobald dies der Fall ist
Was passiert, die Besetzung unten wird scheitern und
// Der Befehl kann nicht mehr abgebrochen werden. Dies kann wünschenswert sein
Der Schließvorgang kann abgebrochen werden, dies ist jedoch der Fall
// außerhalb des Geltungsbereichs von Whidbey RTM. Weitere Informationen finden Sie unter (SqlCommand::Cancel).
sperren.
lock (InnerConnection) {
InnerConnection.CloseConnection(this, ConnectionFactory);
}
// erfordert aufgrund von OnStateChange kein GC.KeepAlive(this).
if (null != Statistik) {
ADP.TimerCurrent(out _statistics._closeTimestamp);
}
#if DEBUG
}
Endlich {
Thread.SetData(TdsParser.ReliabilitySlot, initialReliabilitySlotValue);
}
#endif //DEBUG
}
Catch (System.OutOfMemoryException e) {
Abbruch(e);
werfen;
}
Catch (System.StackOverflowException e) {
Abbruch(e);
werfen;
}
Catch (System.Threading.ThreadAbortException e) {
Abbruch(e);
werfen;
}
Endlich {
SqlStatistics.StopTimer(statistics);
}
}
Endlich {
SqlDebugContext sdc = _sdc;
_sdc = null;
Bid.ScopeLeave(ref hscp);
if (sdc != null) {
sdc.Dispose();
}
}
}
Sie können sehen, dass die Close()-Methode die Dispose()-Methode nicht aufruft. Obwohl es eine Zeile von sdc.Dispose() gibt, gibt diese nur den SqlDebugContext frei.
Instanz, hat nichts mit der SqlConnection.Dispose()-Methode zu tun!
Was ist also der Unterschied?
Die Close()-Methode schließt nur die Verbindung, und dann wird die Verbindung im Verbindungspool gespeichert, sodass Sie nach dem Aufruf der Close()-Methode immer noch weitergeben können
Open()-Methode zum Öffnen der Verbindung und nach Aufruf der Dispose()-Methode kann die Verbindung nicht mehr verwendet werden!
Ein weiterer wichtiger Unterschied besteht darin, dass, wenn die Close()-Methode GC.SuppressFinalize(this); nicht aufruft, die direkte Folge davon Müll ist.
Während des Recyclings sind Beendigungsvorgänge erforderlich, wodurch sich das „Generationsalter“ dieser Instanz erhöht und dadurch die Recyclingzeit dieses Objekts erheblich verzögert!
Wenn Sie diese Verbindung für die SqlConnection-Klasse in Zukunft verwenden müssen, können Sie die Verbindung mithilfe der Close()-Methode vorübergehend schließen.
Um diese Verbindung zu nutzen, können Sie zunächst die Methode Dispose() verwenden, um Ressourcen freizugeben. Natürlich können Sie diesen Vorgang auch mit dem Schlüsselwort using vereinfachen.
Ich habe den Quellcode der OleDbConnection-Klasse und der OdbcConnection-Klasse nicht gefunden, aber sie sollten der SqlConnection-Klasse ähneln!
Schauen wir uns eine häufig verwendete Klasse an und sehen den Unterschied zwischen der Close()-Methode und der Dispose()-Methode der FileStream-Klasse:
Die Close()-Methode der FileStream-Klasse wird von der Stream-Klasse geerbt. Der Quellcode lautet wie folgt:
öffentliche virtuelle Leere Close()
{
Entsorgen(true);
GC.SuppressFinalize(this);
}
Die Dispose()-Methode der FileStream-Klasse wird von der Stream-Klasse geerbt. Der Quellcode lautet wie folgt:
public void Dispose()
{
Schließen();
}
Es handelt sich um eine Implementierung des Standard-Dispose-Modus. Die Close()-Methode ruft die Dispose-Methode mit Parametern auf und ruft dann GC.SuppressFinalize auf.
(this); Fordert das System auf, den Finalizer des angegebenen Objekts nicht aufzurufen. Die Dispose()-Methode ruft direkt die Close()-Methode auf!
Für die FileStream-Klasse gibt es keinen Unterschied zwischen der Close()-Methode und der Dispose()-Methode!