Pergunta

Eu costumo usar código assim:

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

Vai meu command descartado automaticamente? Ou não e eu tenho que envolvê -lo using quadra? É necessário descartar SqlCommand?

Foi útil?

Solução

Apenas faça isso:

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

Não ligar para dispensar o comando não fará nada de ruim. No entanto, chamando dispõe nele irá suprime a chamada para o finalizador, fazendo com que a chamada descarte um aprimoramento de desempenho.

Outras dicas

A política mais segura é sempre ligar Dispose() em um objeto, se ele implementar IDisposable, explicitamente ou através de um bloco de uso. Pode haver casos em que não é necessário, mas chamá -lo de qualquer maneira nunca deve causar problemas (se a classe estiver escrita corretamente). Além disso, você nunca sabe quando uma implementação pode mudar o significado que, onde a chamada não era necessária anteriormente, ela é definitivamente necessária.

No exemplo que você deu, você pode adicionar um bloqueio interno extra para o comando, além de manter o bloco externo usando a conexão.

Sim, você deve, mesmo que a implementação não esteja fazendo muito, não sabe como será alterado no futuro (versões mais recentes da estrutura, por exemplo). Em geral, você deve descartar todos os objetos que implementam IDisposable estar do lado seguro.

No entanto, se a operação for adiada e você não controlar o escopo completo (por exemplo, ao trabalhar de forma assíncrona, ou ao devolver um SqlDataReader ou assim), você pode definir o CommandBehavior para CloseConnection Para que, assim que o leitor for concluído, a conexão está devidamente fechada/descartada para você.

Você pode descobrir esse tipo de coisa usando Refletor ou DotPeek ou https://referencesource.microsoft.com/.

Eu tive uma pequena escavação (eu sugiro que você se cansasse, embora tenha certeza do resto disso, pois não tentas com essa conexão. Além disso, na verdade não parece que o descarte de um comando realmente faz isso. Ele definirá um campo para NULL, se destacar de um contêiner (isso pode impedir um vazamento de memória gerenciada) e aumentar um evento (isso pode ser importante, mas não consigo ver quem está ouvindo este evento).

De qualquer forma, é uma boa prática usar essas coisas em um bloco de uso ou para garantir que você o descarte usando um padrão de descarte no objeto que mantém a conexão (se você pretende manter o comando por um tempo).

Na prática, você pode pular Dispose. Não libera nenhum recurso. Nem sequer suprime a finalização desde O construtor SQLCommand faz isso.

Em teoria, a Microsoft poderia mudar a implementação para manter um recurso não gerenciado, mas eu espero que eles saíssem com uma API que se livra do Component Classe base muito antes de fazê -lo.

Na minha opinião, chamando Dispose para ambos SqlConnection e SqlCommand é uma boa prática, use o código abaixo

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();
}
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top