Question

J'utilise généralement un code comme celui-ci:

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

Ma commande sera-t-elle automatiquement supprimée? Ou pas et je dois l'envelopper dans en utilisant bloc? Est-il nécessaire de disposer de SqlCommand ?

Était-ce utile?

La solution

Faites ceci:

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

Ne pas appeler dispose de la commande ne fera rien de mal. Toutefois, l'appel de Dispose sur ce dernier annulera l'appel du finaliseur , ce qui fait que les appels disposent d’une amélioration des performances.

Autres conseils

La politique la plus sûre consiste à toujours appeler Dispose () sur un objet s'il implémente IDisposable , explicitement ou via un bloc using. Il peut y avoir des cas où cela n’est pas requis mais l’appel de toute façon ne devrait jamais causer de problèmes (si la classe est écrite correctement). En outre, vous ne savez jamais à quel moment une implémentation peut changer, ce qui signifie que, là où l'appel n'était pas requis auparavant, il l'est désormais.

Dans l'exemple que vous avez donné, vous pouvez ajouter un bloc d'utilisation interne supplémentaire pour la commande, ainsi que conserver le bloc d'utilisation externe pour la connexion.

Oui, vous devriez, même si la mise en œuvre ne fait actuellement pas grand chose, vous ne savez pas comment cela va changer à l'avenir (par exemple, les versions plus récentes du framework). En règle générale, vous devez supprimer tous les objets qui implémentent IDisposable .

Toutefois, si l'opération est différée et que vous ne contrôlez pas l'étendue complète (par exemple, lorsque vous travaillez de manière asynchrone ou lorsque vous retournez un SqlDataReader ou une autre), vous pouvez définir le CommandBehavior à CloseConnection afin que, dès que le lecteur soit terminé, la connexion soit correctement fermée / supprimée pour vous.

Vous pouvez découvrir ce genre de choses en utilisant Reflector ou dotPeek ou < a href = "https://referencesource.microsoft.com/" rel = "nofollow noreferrer"> https://referencesource.microsoft.com/ .

J'ai eu une petite fouille (je vous suggérerais de vous creuser vous-même pour être tout à fait sûr du reste, car je n'ai pas essayé aussi durement) et il semblerait que lorsque vous tuez une connexion, il n'y a pas de tous les enfants associés à cette connexion. De plus, il ne semble pas que la disposition d'une commande en fasse autant. Il définira un champ sur null, se détachera d'un conteneur (cela peut empêcher une fuite de mémoire gérée) et déclenchera un événement (cela peut être important mais je ne peux pas voir qui écoute cet événement).

Dans tous les cas, il est recommandé d’utiliser ce contenu dans un bloc using ou de s’assurer de le supprimer en utilisant un motif de disposition dans l’objet qui contient la connexion (si vous souhaitez conserver la commande pendant un moment).

En pratique, vous pouvez ignorer Éliminer . Cela ne libère aucune ressource. Elle ne supprime même pas la finalisation depuis le Le constructeur SQLCommand le fait .

En théorie, Microsoft pourrait modifier l'implémentation pour contenir une ressource non gérée, mais j'espère qu'ils sortiront avec une API supprimant bien avant la classe de base Component ça.

À mon avis, appeler Dispose pour SqlConnection et SqlCommand constitue une bonne pratique, utilisez le code ci-dessous

.
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();
}
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top