Persönlich breche ich in Hives aus, wenn ich ADO-Objekte, die IDisposable implementieren, nicht in using-Anweisungen setze. Bei meinem aktuellen Vertrag habe ich jedoch festgestellt, dass der von ihnen selbst entwickelte Code des Enterprise-Frameworks "Data Access Provider" nicht 1) IDisposable implementiert und 2) Dispose () für alles, was es verwendet, zu irgendeinem Zeitpunkt jemals aufruft. Benutzer haben sich viel über Leistungsprobleme in den Winforms-Anwendungen beschwert, die dieses Framework für den Datenzugriff stark nutzen, und obwohl es eine Menge anderer Probleme im Code gibt, die die Leistung beeinträchtigen könnten, schreit mich dieser nur an und ist mehr niedrig hängende Früchte als die anderen.
Was kann ich diesen Leuten sagen, um sie davon zu überzeugen, dass dies wirklich sehr, sehr schlecht ist?
quelle
Antworten:
Ich würde sagen , das Beste , was Sie tun können , ist , sie zu Microsofts Mustern zeigen und Praktiken in Bezug auf
Dispose()
hier . Lassen Sie sie sehen, welche Konsequenzen es hat, wenn sie dieses Tool, das direkt vor ihnen liegt, nicht nutzen.quelle
Wenn Sie die Dispose-Methode für eine SQL-Verbindung nicht aufrufen, wird diese Verbindung nach Abschluss der Verwendung NICHT wieder an den Verbindungspool zurückgegeben.
Wenn Sie Leistungsprobleme haben, ist meine Vermutung, dass die maximale Anzahl von Verbindungen in Ihrer Datenbank geöffnet ist. Ein DBA könnte dies leicht bestätigen.
Microsoft's Best Practice fordert Sie auf, Ihren Verbindungscode in eine Using-Anweisung einzufügen, um sicherzustellen, dass die Verbindung gelöscht und die Verbindung wieder in den Pool zurückgegeben wird.
quelle
Close
ist ausreichend, um die Freigabe an den Verbindungspool zurückzusetzen. Die Frage besagt nicht, dass diesClose
nicht explizit verwendet wird.Der Datenbankverbindungspool ist in seiner Größe begrenzt. Wenn er voll ist, warten neue Verbindungen darauf, dass alte Verbindungen freigegeben werden. Wenn Sie sie nicht entsorgen, sobald Sie fertig sind, werden sie irgendwann veröffentlicht, wenn der Finalizer ausgeführt wird, aber das ist eine unbestimmte Zeit in der Zukunft ... Also, im besten Fall Es treten lange Verzögerungen auf, wenn neue Verbindungen hergestellt werden.
Im schlimmsten Fall haben sie möglicherweise den Verbindungspool deaktiviert. Vielleicht stellten sie fest, dass ihre App nach einer Weile "Wartezeit auf Verbindungsfehler" zurückgab und das Deaktivieren des Verbindungspools dieses Problem "löste". Dies ist jedoch viel schlimmer, da Sie jedes Mal eine ganz neue Verbindung erstellen - was überraschend ressourcenintensiv ist. Wenn Sie Hunderte von Verbindungen zur Datenbank geöffnet haben, ist es kein Wunder, dass Sie Leistungsprobleme feststellen.
Der richtige Weg, um all diese Probleme zu lösen, besteht darin, Ihre Verbindung zu entsorgen, sobald Sie damit fertig sind. Die beste Idee ist, die Verbindung so lange wie nötig offen zu halten und nicht länger.
quelle
Bei jeder ernsthaften Anwendung würde ich sagen, dass es ziemlich schlecht ist. Diese Objekte können nicht nur die Leistung eines Killers beeinträchtigen, sondern sind auch einfach unprofessionell. Die gute Nachricht ist, dass Microsoft Finalize in der Objekthierarchie implementiert.
Nehmen Sie
System.Data.SqlClient.SqlConnection
zum Beispiel:Die Objekte werden irgendwann entsorgt, aber die nicht deterministische Natur beeinträchtigt die Leistung.
quelle
Zum einen beenden Sie die Verbindung nicht. Es muss also entweder a) automatisch gelöscht werden oder b) durchlaufen und aktualisiert werden, obwohl der Client keine Verwendung dafür hat.
Ich würde annehmen, b) wegen des Performance-Hits, den Sie beschreiben. Dies ist jedoch wahrscheinlich nicht der einzige Grund.
Sie MÜSSEN Ihre Verbindungen schließen, vorzugsweise auf der Clientseite, aber Sie müssen auch eine Ausfallsicherung auf der Serverseite implementieren. Andernfalls haben Sie nur zusätzlichen Mist, den Ihr Datenbankserver verarbeiten muss, bis er bei Gott-weiß-wann veröffentlicht wird.
quelle