Warum SqlClient.SqlDataReader Close () Methode trotzdem aufrufen?
Ist der SqlClient.SqlDataReader ein .NET-verwalteten Objekt oder nicht?
Warum haben wir Sie zum aufrufen der Methode Close() explizit zu schließen, eine offene Verbindung?
Sollte läuft nicht out-of-scope für ein Objekt automatisch schließen?
Sollte das nicht garbage collector-reinigen Sie es sowieso?
Bitte helfen Sie mir zu verstehen, was ist die beste Praxis hier.
Habe ich gesehen, dass eine Frage im Zusammenhang mit hier und es zeigt das Problem, das ich habe mit einer web-Anwendung. Das Problem ist, dass wir verbindungen zur Verfügung. Die detaillierte Fehlermeldung ist hier:
Exception: System.InvalidOperationException
Message: Timeout expired. The timeout period elapsed prior to obtaining a connection from the pool. This may have occurred because all pooled connections were in use and max pool size was reached.
Source: System.Data
at System.Data.SqlClient.SqlConnectionPoolManager.GetPooledConnection(SqlConnectionString options, Boolean& isInTransaction)
at System.Data.SqlClient.SqlConnection.Open()
Um dies zu beheben, musste ich explizit schließen Sie alle SQLDataReader-Objekten.
Ich bin mit .NET Framework 3.5
InformationsquelleAutor der Frage Julius A | 2008-10-30
Du musst angemeldet sein, um einen Kommentar abzugeben.
Sicher, es wird gesammelt, wenn es den Bereich verlässt (wenn keine anderen Verweise darauf). Wenn Sie gesammelt ist, wird Sie geschlossen durch seine Dispose () - Methode. Jedoch, Sie wissen nie wirklich, Wann die GC wird deallocate Dinge, wenn Sie nicht schließen Sie Ihre Leser, Sie sehr schnell aus der verfügbaren verbindungen an die Datenbank.
Weiter Lesen
~ William Riley-Land
InformationsquelleAutor der Antwort wprl
@Leutnant Frost
Habe ich eine ähnliche Regel, aber ich verlange, dass Objekte, die IDisposable implementieren, verwenden Sie die 'mit' - block.
Den using-block Anrufe Entsorgen Sie sofort beim verlassen der Bereich, auch mit einer Ausnahme.
InformationsquelleAutor der Antwort FlySwat
Einer guten Praxis (solange Sie nicht re-verwenden von verbindungen) ist, um den Befehl hinzufügen, der das Verhalten der SqlDataReader schließen die Verbindung, wenn es wird entsorgt:
Hinzufügen damit wird sichergestellt, dass die Verbindung zur Datenbank wird geschlossen, wenn das SqlDataReader-Objekt geschlossen ist (oder garbage Collection).
Wie gesagt, wenn Sie nicht wollen, dies zu tun, wenn Sie planen, auf eine erneute Verwendung der Datenbank-Verbindung für einen anderen Betrieb innerhalb der gleichen Methode.
InformationsquelleAutor der Antwort Jeffrey Harrington
Ich denke, jeder wird anderes gesagt, aber ich wollte es klar zu sein:
Out of scope bedeutet nicht die sofortige garbage collection.
Muss die app "play nice" auf mehreren Ebenen.
Schließen Sie die verbindungen, die Sie dabei unterstützen.
Lassen Sie ' s untersuchen ein paar von diesen Ebenen.
1: Sie sind nicht unter Berufung auf die garbage collection.
Idealerweise garbage collection sollte nicht vorhanden sein müssen. Aber das tut es.
Aber ganz gewiss sollte man sich nicht verlassen auf Sie.
2: Sie nicht halten Sie Ihre Datenbank-verbindungen.
Während die verbindungen werden in der Regel gebündelt, wie hast du Sie gefunden, gibt es eine Grenze.
Halten diese länger als nötig macht Ihre app den schlechten apple.
3: Sie sich nicht die Generierung von Netzwerk-traffic.
Jede Datenbank-Verbindung ist im wesentlichen ein TCP-Verbindung.
Halten Sie es offen, wahrscheinlich erzeugt Netzwerk-Verkehr entlang der Linien von
Sind Sie noch da? ja.
Kleiner Verkehr ja, aber auf einem überfüllten Netzwerk dies ist eine schlechte Praxis.
Und SQL Server selbst über Ressourcen, um Ihre Verbindung aufrecht.
Ressourcen, die anderen Menschen, die versuchen zu lernen, den sql server könnten besser nutzen.
Wenn das denken über den Datenbank-Zugriff Sie müssen auch darüber nachdenken, Netzwerk-Ressourcen.
Einige Möglichkeiten, um die Daten schlecht sind, weil Sie bringen unnötige Sachen für die Fahrt entlang. Die früheren Versionen von ADO waren berüchtigt für diese Art von Sachen. Womit wieder die schema-Informationen, wenn Sie wollen einfach nur die Daten. Sicher, mit nur wenigen verbindungen ist dies kein problem. Aber seit Wann hat jeder Datenbank nur ein paar verbindungen. Also denken Sie über diese Dinge und versuchen Sie nicht, um Missbrauch der Ressourcen.
Wenn Sie Ihre web-app hat nur 100 Benutzer, die Sie möglicherweise nicht wichtig.
Aber was etwa 100.000? Immer überlegen, was passiert, wenn Sie die Skala.
InformationsquelleAutor der Antwort Will Rickards
Wenn Sie nicht explizit schließen, dann sitzt es da und wartet, dass der garbage collector zu "sammeln"... Nur danach passiert, wird es wieder freigegeben, um die ADO.Net Verbindungspool wiederverwendet werden, indem Sie eine andere Verbindung.Open request, also während der ganzen Zwischenzeit, alle anderen Anfragen für eine Verbindung zu erstellen Sie einen neuen Marke ein, obwohl es eine ganz gute man sitzt da unbenutzt, die verwendet werden könnte...
Je nachdem, wie lange es dauern wird, bevor der GC läuft, und wie viele Datenbank-Anfragen ausgeführt werden, man könnte aus den vorhandenen verbindungen zur Datenbank.
Aber es gibt einen optionalen parameter auf der Kommandozeile.ExecuteReader () - Methode aufgerufen, CommandBehavior. Dies ist eine Aufzählung mit den Werten:
CommandBehavior.Standard, CommandBehavior.SingleResult, CommandBehavior.SchemaOnly, CommandBehavior.KeyInfo, CommandBehavior.SingleRow, CommandBehavior.SequentialAccess, und CommandBehavior.CloseConnection
Diese enumeration verfügt über ein FlagsAttribute-Attribut, das ermöglicht eine bitweise Kombination der memberwerte. Es ist der Letzte Wert, (CommandBehavior.CloseConnection), die hier relevant ist. Es erzählt die Command-Objekts, um die Verbindung zu schließen, wenn der data-reader ist geschlossen.
http://msdn.microsoft.com/en-us/library/system.data.commandbehavior.aspx
Leider der Standard ist, NICHT die Verbindung schließen, wenn der data-reader ist geschlossen, aber Sie können (und sollten) diesen parameter übergeben, als CommandBehavior.CloseConnection-wenn Sie möchten, dass Ihre Methode zum lösen der Verbindung wieder an den pool sofort, wenn Sie fertig sind...
InformationsquelleAutor der Antwort Charles Bretana
Den 'managed' Ressource bezeichnet der Begriff 'managed code' ist Speicher. Das ist es. Jede andere knappe Ressource muss gewickelt werden, die mit den Einweg-Muster, einschließlich der Datenbank-verbindungen.
Der Grund dafür ist ein problem für Sie ist, dass die Speicherbereinigung nicht ausgeführt wird für jedes Objekt der moment, es geht out of scope. Es ist viel effizienter sammeln, um mehr Elemente, die weniger Häufig. Also, wenn Sie warten, bis die Kollektor-entsorgen Sie Ihre Objekte (und ja, wenn Sie implementieren idisposable es schließlich), die Sie vielleicht halten eine Anzahl von Datenbank-verbindungen geöffnet haben, viel länger, als Sie denken.
InformationsquelleAutor der Antwort Joel Coehoorn
Auch berücksichtigen, was passiert, wenn eine exception wird geworfen - man weiß nie, wenn die Verbindung wird geschlossen, wenn Sie plötzlich gezwungen, aus dem code ausführen.
Als Regel in unseren shop, wir haben ausdrücklich wickeln Sie alle Datenbank-Aufrufe in einem Try...Finally-block, mit dem schließlich Abschnitt fangen und schließen Sie die Daten-verbindungen. Es lohnt sich, das kleine bisschen Mühe zu sparen, sich einer wichtigen Fehlerbehebung Kopfschmerzen.
InformationsquelleAutor der Antwort Lieutenant Frost
Ist es nicht der Anschluss ist das problem, sondern die SQL-Cursor in den Händen gehalten, die SqlDataReader. Wenn Sie versuchen, öffnen Sie ein zweites ohne schließen der ersten, es wird eine Ausnahme ausgelöst.
InformationsquelleAutor der Antwort James Curran