2010-01-07 13 views
5

Vor einiger Zeit habe ich eine ORM-Ebene für meine .net-App geschrieben, in der alle Datenbankzeilen durch eine Unterklasse von DatabaseRecord repräsentiert werden. Es gibt eine Reihe von Methoden wie Load(), Save() usw. In meiner ursprünglichen Implementierung erstellte ich eine Verbindung zu der DB im Konstruktor DatabaseRecord z.Overhead zum Erstellen neuer SqlConnection in C#

connection = new SqlConnection(
    ConfigurationManager.ConnectionStrings["ConnectionName"].ConnectionString 
); 

Ich rufe dann Open() und Close() an diesem SqlConnection am Anfang und Ende meiner Methoden, die auf die Datenbank zugreifen. Dies schien mir (als jemand, der mit Programmierung vertraut war, aber neu in C# und .net) die effizienteste Art und Weise zu sein, Dinge zu tun - eine Verbindung zu haben und sie innerhalb der Klasse zu öffnen/schließen.

Ich habe gerade etwas zu lesen, obwohl getan und es scheint, dass dieses Muster in einer Reihe von Orten empfohlen:

using (var connection = new SqlConnection(...)) { 
    connection.Open(); 
    // Stuff with the connection 
    connection.Close(); 
} 

Ich kann sehen, warum es wünschenswert ist - die Verbindung automatisch Dispose() ist d auch wenn die Sachen, die du in der Mitte machst, verursachen eine nicht abgefangene Ausnahme. Ich habe mich nur gefragt, was der Overhead ist, um so viele Male wie diese new SqlConnection() zu nennen.

Connection Pooling ist eingeschaltet, daher stelle ich mir vor, dass der Overhead minimal ist und der zweite Ansatz sollte die beste Vorgehensweise sein, aber ich wollte nur sicherstellen, dass meine Annahmen richtig sind.

+0

Vielen Dank für all die angeordnet ist, unglaublich schnelle Antworten! – vitch

Antwort

8

Ja, es ist die beste Vorgehensweise. Die using macht Ihren Aufruf an Close() ausnahmesicher.

Und der Overhead zum Erstellen eines (beliebigen) Objekts ist tatsächlich minimal und am kleinsten für kurzlebige Objekte (die in der GC-Generation 0 bleiben).

Beachten Sie, dass Sie am Ende des using-Blocks nicht mehr Close() aufrufen müssen, es wird automatisch für Sie erledigt (Dispose == Close).

+0

Wie minimal? Gibt es irgendwo Benchmarks, die zeigen, wie viel Leistung beim Öffnen und Schließen von Verbindungen verloren geht? Gibt es einen Netzwerk-Handshake, der ausgeführt wird, wenn die Open-Methode aufgerufen wird? –

+0

Eigentlich denke ich, dieser Artikel beantwortet meine Frage perfekt. https://docs.microsoft.com/en-us/dotnet/framework/data/adonet/sql-server-connection-pooling –

+0

Wenn dieser Artikel korrekt ist, sollte Verbindungspooling explizit mit Handshake usw. umgehen.und stellen Sie sicher, dass kein unnötiges Handshaking stattfindet. –

1

Dies ist teilweise eine Frage des Geschmacks. Solange Sie das Verbindungs-Pooling verwenden, ist der Aufwand für das Erstellen eines neuen Projekts (Wiederverwerten einer gepoolten Verbindung) minimal. Im Allgemeinen wird empfohlen, neue Verbindungsobjekte nach Bedarf zu erstellen.

Wenn Sie mehrere Befehle sofort nacheinander ausführen, sehe ich keinen Grund, neue Verbindungen für jede von ihnen zu erstellen, aber Sie sollten vermeiden, für eine lange Zeit Verbindungen zu öffnen.

Auch sollten Sie beachten, dass die Dispose Methode die Verbindung für Sie schließt. Sie müssen also nicht Close und Dispose anrufen. Da die using -Klausel nach Ende des Gesprächs abruft, ist es normalerweise nicht erforderlich, Close aufzurufen.

1

Wenn Sie sich nicht sicher über die Kosten des Öffnungs-/Schließ Verbindung, haben die SqlConnection eine Membervariable der Klasse, sondern macht die Klasse IDisposable und den SqlConnection entsorgen, wenn die Klasse

+0

Eigentlich denke ich darüber nach, dass dies der effizientere Ansatz sein könnte. Ich habe Ihren Vorschlag ein wenig in einer anderen Frage konkretisiert - es wäre großartig, wenn Sie mich wissen lassen könnten, wenn ich richtig verstanden habe: http://stackoverflow.com/questions/2020576/creating-an-idisposable-class-in -c-was-bereinigt-eine-sql-Verbindung-wenn-finishe – vitch

Verwandte Themen