Frage

Normalerweise verwende ich einen solchen Code:

using (var connection = new SqlConnection(ConfigurationManager.ConnectionStrings["MyConn"].ConnectionString))
{
   var command = connection.CreateCommand();
   command.CommandText = "...";
   connection.Open();
   command.ExecuteNonQuery();
}

Wird mein command automatisch entsorgt? Oder nicht und ich muss es einwickeln using Block? Ist es erforderlich, zu entsorgen? SqlCommand?

War es hilfreich?

Lösung

Mach das einfach:

using(var connection = new SqlConnection(ConfigurationManager.ConnectionStrings["MyConn"].ConnectionString))
using(var command = connection.CreateCommand())
{
   command.CommandText = "...";
   connection.Open();
   command.ExecuteNonQuery();
}

Nicht anrufen, das den Befehl entsetzt, wird nichts schlechtes tun. Die Anrufung wird jedoch entsorgen Verklemmen Sie den Anruf zum Finalizer, Anrufen zu machen, entsorgen Sie eine Leistungsverbesserung.

Andere Tipps

Die sicherste Richtlinie besteht darin, immer anzurufen Dispose() auf einem Objekt, wenn es impliziert IDisposable, entweder explizit oder über einen Block mithilfe von Block. Es kann Fälle geben, in denen es nicht erforderlich ist, aber es ohnehin anrufen sollte, sollte niemals Probleme verursachen (wenn die Klasse korrekt geschrieben ist). Außerdem wissen Sie nie, wann eine Implementierung sich ändern kann, was bedeutet, dass der Anruf, der bisher nicht erforderlich war, jetzt definitiv erforderlich ist.

Im Beispiel, das Sie angegeben haben, können Sie einen zusätzlichen inneren Block für den Befehl hinzufügen und den äußeren mithilfe von Block für die Verbindung beibehalten.

Ja, Sie sollten, selbst wenn die Implementierung derzeit nicht viel tut, Sie wissen nicht, wie sie in Zukunft verändert werden wird (neuere Rahmenversionen zum Beispiel). Im Allgemeinen sollten Sie alle Objekte entsorgen, die implementiert werden IDisposable auf der sicheren Seite sein.

Wenn die Operation jedoch aufgeschoben wird und Sie den vollständigen Umfang nicht kontrollieren (zum Beispiel bei asynchrone Arbeit SqlDataReader oder so) können Sie die festlegen CommandBehavior zu CloseConnection sobald der Leser fertig ist, ist die Verbindung für Sie ordnungsgemäß geschlossen/entsorgt.

Sie können diese Art von Dingen mithilfe der Dinge herausfinden Reflektor oder Dotpeek oder https://referencesource.microsoft.com/.

Ich hatte eine kleine Ausgrabung (ich würde vorschlagen, dass Sie sich selbst graben, um sich des Restes jedoch ganz sicher zu sein, da ich mich nicht so sehr bemüht habe), und es sieht so aus mit dieser Verbindung. Außerdem sieht es nicht so aus, als ob die Entsorgung eines Befehls tatsächlich so viel tut. Es setzt ein Feld auf Null, löst sich von einem Container (dies kann ein verwaltetes Speicherleck verhindern) und erhöhen ein Ereignis (dies könnte wichtig sein, aber ich kann nicht sehen, wer dieses Ereignis hört).

In beiden Fällen ist es eine gute Praxis, dieses Zeug in einem verwendeten Block zu verwenden oder sicherzustellen, dass Sie es mit einem Entsetztmuster in dem Objekt entsorgen, das die Verbindung hält (wenn Sie den Befehl für eine Weile festhalten möchten).

In der Praxis können Sie überspringen Dispose. Es befreien keine Ressourcen. Es unterdrückt nicht einmal die Abschlüsse, da die SQLCommand Constructor macht das.

Theoretisch könnte Microsoft die Implementierung ändern, um eine nicht verwaltete Ressource zu halten, aber ich würde hoffen, dass sie mit einer API herauskommen würden, die das beseitigt Component Basisklasse lange bevor sie das tun würden.

Meiner Meinung nach rufen Sie an Dispose für beide SqlConnection und SqlCommand ist eine gute Praxis, verwenden Sie den folgenden Code

using(var connection = new SqlConnection(ConfigurationManager.ConnectionStrings["MyConn"].ConnectionString))
try{
    using(var command = connection.CreateCommand())
    {
       command.CommandText = "...";
       connection.Open();
       command.ExecuteNonQuery();
    }
}
catch(Exception ex){ //Log exception according to your own way
    throw;
}
finally{
    command.Dispose();
    connection.Close();
    connection.Dispose();
}
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top