Após ler os tópicos, o SqlCommand.Dispose é suficiente? e Fechando e descartando um serviço WCF Estou pensando em classes como SqlConnection ou em uma das várias classes herdadas da classe Stream. Importa se eu fechar Dispose em vez de Close?
Após ler os tópicos, o SqlCommand.Dispose é suficiente? e Fechando e descartando um serviço WCF Estou pensando em classes como SqlConnection ou em uma das várias classes herdadas da classe Stream. Importa se eu fechar Dispose em vez de Close?
Respostas:
De acordo com as diretrizes da Microsoft, é uma boa prática fornecer o Closemétodo adequado. Aqui está uma citação das diretrizes de design do Framework
Considere fornecer o método
Close(), além doDispose(), se close é uma terminologia padrão na área. Ao fazer isso, é importante que você torne aCloseimplementação idêntica aDispose...
Na maioria dos casos Closee Disposemétodos são equivalentes. A principal diferença entre Closee Disposeno caso de SqlConnectionObjecté:
Um aplicativo pode ligar
Closemais de uma vez. Nenhuma exceção é gerada.Se você chamou o estado do objeto de
DisposemétodoSqlConnection, será redefinido. Se você tentar chamar qualquer método noSqlConnectionobjeto descartado , receberá uma exceção.
Dito isto:
Dispose.Closemétodocon.Open() con.Close(); 2 con.Open(); // reuse 3. con.Dispose(); // use one time con.Open(); // error
Como sempre, a resposta é: depende. Diferentes classes são implementadas de IDisposablemaneiras diferentes, e cabe a você fazer a pesquisa necessária.
Na medida do possível SqlClient, a prática recomendada é fazer o seguinte:
using (SqlConnection conn = /* Create new instance using your favorite method */)
{
conn.Open();
using (SqlCommand command = /* Create new instance using your favorite method */)
{
// Do work
}
conn.Close(); // Optional
}
Você deve ligar Dispose(ou Close*) na conexão! Você não esperar para o coletor de lixo para limpar a sua conexão, isso vai amarrar conexões na piscina até o próximo ciclo de GC (pelo menos). Se você ligar Dispose, não é necessário ligar Closee, como a usingconstrução facilita o manuseio Disposecorreto, não há realmente motivo para ligar Close.
As conexões são agrupadas automaticamente e a ligação Dispose/ Closeconexão não a fecha fisicamente (em circunstâncias normais). Não tente implementar seu próprio pool. SqlClientexecuta limpeza na conexão quando é recuperada do pool (como restaurar o contexto do banco de dados e as opções de conexão).
* se você estiver ligando Close, certifique-se de fazê-lo de maneira segura contra exceções (ou seja, em uma captura ou, finalmente, em um bloco).
conn.Close(); // Optionalnão é opcional. É redundante e desnecessário. Você está descartando o objeto duas vezes e isso será marcado como um aviso por algumas ferramentas de análise de código.
using (var x = ..) { x.Dispose(); }, caso em que xrealmente é "descartado duas vezes".
Você precisa chamar Dispose ()!
Dispose () é para o desenvolvedor chamar, o Garbage Collector chama Finalize (). Se você não chamar Dispose () em seus objetos, os recursos não gerenciados que eles usaram não serão descartados até que o coletor de lixo chegue e chame a finalização deles (e quem sabe quando isso acontecerá).
Esse cenário é chamado de Finalização não determinística e é uma armadilha comum para desenvolvedores .net. Se você estiver trabalhando com objetos que implementam IDisposable, chame Dispose () neles!
http://www.ondotnet.com/pub/a/oreilly/dotnet/news/programmingCsharp_0801.html?page=last
Embora possa haver muitas instâncias (como em SqlConnection) em que você chama Disponse () em algum objeto e simplesmente chama Close () em sua conexão ou fecha um identificador de arquivo, quase sempre é sua melhor opção chamar Dispose ()! a menos que você planeje reutilizar o objeto em um futuro próximo.
Dispose.
Dispose() se não estiver usando using()uma classe que implementa IDisposable. Se a classe que está sendo chamada implementa IDisposable e você incluiu seu uso na página interna using(), é possível descartar com o Dispose()(trocadilho intencional, então atire em mim). Close()No entanto, é recomendável usar qualquer coisa que utilize explicitamente o Open()AFAIK.
Closeconectar-se, o Postgres define automaticamente o identificador de conexão como null. A partir daí, não é possível Disposeum identificador de conexão sql que já esteja definido como null.
Pois SqlConnection, da perspectiva da própria conexão, eles são equivalentes. De acordo com o Reflector, Dispose()chamadas Close(), além de realizar algumas operações adicionais de liberação de memória - principalmente configurando membros como nulos.
Para o Stream, eles são realmente equivalentes. Stream.Dispose()simplesmente chama Close ().
Component qual parece não fazer nada para tentar ligarClose() . Não consigo ver nenhum lugar DBConnectionou SqlConnectionque esteja vinculado a nenhuma dessas notificações. No entanto, possui um particular DisposeMe()que não é referenciado em nenhum lugar .
Esse possível conselho rápido tornou-se uma resposta longa. Desculpe.
Como Tyler apontou em sua bela resposta, chamar Dispose()é uma ótima prática de programação. Isso ocorre porque esse método deve "reunir" toda a liberação de recursos necessária para que não haja recursos abertos desnecessários. Se você escreveu algum texto em um arquivo, por exemplo, e não conseguiu fechar o arquivo (liberar o recurso), ele permanecerá aberto e ninguém mais poderá gravá-lo até que o GC chegue e faça o que você deveria feito.
Agora, em alguns casos, haverá métodos de "finalização" mais específicos da classe com a qual você está lidando StreamWriter.Close(), que substitui TextWriter.Close(). De fato, eles geralmente são mais adequados à situação: um StreamWriter Close(), por exemplo, libera o fluxo e o codificador subjacente antes Dispose()da entrada do objeto! Legal!
No entanto, navegando no MSDN, você verá que até a Microsoft às vezes fica confusa com a multidão de closers e trituradores. Nesta página da Web , por exemplo, em alguns exemplos Close()é chamado antes do implícito Dispose()(consulte a instrução using, se você não entende por que está implícito), e em um em particular eles não se preocupam. Por que isso seria? Eu também fiquei perplexo.
A razão pela qual eu imaginei (e, enfatizo, essa é uma pesquisa original e, com certeza, posso perder a reputação se estiver errada) é que Close()pode falhar, gerando uma exceção ao mesmo tempo em que deixa os recursos abertos, e Dispose()certamente os liberaria . É por isso que a Dispose()deve sempre salvaguardar uma Close()ligação (desculpe pelo trocadilho).
MyResource r = new MyResource();
try {
r.Write(new Whatever());
r.Close()
finally {
r.Dispose();
}
E sim, acho que a Microsoft escorregou nesse exemplo. Talvez esse carimbo de data e hora nunca seja liberado para o arquivo.
Estou corrigindo meu código antigo amanhã.
Edit: desculpe, Brannon, não posso comentar sua resposta, mas você tem certeza de que é uma boa ideia chamar Close()um finallybloco? Eu acho que uma exceção disso pode arruinar o resto do bloco, o que provavelmente conteria um código de limpeza importante.
Resposta para Brannon's: ótimo, mas não se esqueça de ligar Close()quando for realmente necessário (por exemplo, ao lidar com fluxos - não saiba muito sobre conexões SQL no .NET).
Typecast para iDisposable e ligue para descartá-lo. Isso invocará qualquer método que esteja configurado para implementar "iDisposable.Dispose", independentemente do nome da função.
IDisposable.Dispose, mas isso não significa que esse seja o nome. Observe que no vb.net é possível vincular uma função a vários membros da interface com nomes que não precisam estar relacionados ao da função.
using (myObj as IDisposable)
Geralmente, estamos enfrentando problemas em Close (), Abort () e Dispose (), mas deixe-me dizer a diferença entre eles.
1) ABORT: - Não sugiro usar isso porque quando o abort é chamado, o cliente exclui a conexão sem informar o servidor, para que o servidor aguarde um certo período de tempo (aproximadamente 1 minuto). Se você tiver uma solicitação em massa, não poderá usar abort () porque isso pode causar um tempo limite para o seu pool de conexões limitado.
2) Fechar: - Fechar é uma maneira muito boa de fechar a conexão, pois ao fechar a conexão, ele chamará o servidor e reconhecerá que o servidor também fecha por esse lado.
Aqui, mais uma coisa para procurar. Em alguns casos, se o erro é gerado, não é uma boa maneira de escrever código finalmente nessa connection.close () porque, naquele momento, o Estado da Comunicação estará com falha.
3) Descarte: - É um tipo de fechamento, mas depois de fechar a conexão, você não pode abri-la novamente.
Então tente dessa maneira,
private void CloseConnection(Client client)
{
if (client != null && client.State == CommunicationState.Opened)
{
client.Close();
}
else
{
client.Abort();
}
}
client != nullestá incorreta / enganosa porque não protege todos os usos. Além disso, não tenho certeza de como o código pode chegar ao estado "esta conexão não está aberta e deve ser fechada".