Pergunta

Eu tenho um método, que tem um dentro do bloco try/catch/finaly. Dentro do bloco try, declaro SqlDataReader da seguinte forma:

SqlDataReader aReader = null;          
aReader = aCommand.ExecuteReader();

No bloco finally, os objectos que são eliminados manualmente de são aqueles que estão situados ao nível da classe. Então objetos no método que implementar IDisposable, como SqlDataReader acima, eles são automaticamente eliminados? Close() é chamado em aReader depois de um tempo executa de loop para obter o conteúdo do leitor (que deve ser Dispose() como que as chamadas Close()). Se não houver nenhuma chamada para Close(), seria este objeto ser fechado / eliminados automaticamente quando o método de acabamentos ou o objeto sai do escopo?

EDIT:. Estou ciente da declaração using mas há situações que estão me confundindo

Foi útil?

Solução

Não, objetos não são eliminados automaticamente quando eles saem do escopo.

Eles nem mesmo a garantia de ser eliminados se / quando eles estão coleta de lixo, embora muitos IDisposable objetos implementar uma finaliser "fallback" para ajudar a garantir que eles estão, finalmente, eliminados.

Está resposible para assegurar que quaisquer objectos IDisposable são dispostas, de preferência envolvendo-os em um using bloco.

Outras dicas

Você deve usar um bloco using {...} para embrulhar seus objetos IDisposable em - o método Dispose() (que para SqlDataReader passa ao largo ao método Close()) será chamado quando a usar bloco termina. Se você não usar using, o objeto irá não ser eliminados automaticamente quando ele sai do escopo - caberá ao objeto finalizador, se ele tiver um, para se livrar de recursos quando é lixo coletado

using (SqlDataReader aReader = aCommand.ExecuteReader())
{
    // ... do stuff
}   // aReader.Dispose() called here

O padrão Dispose não faz quaisquer garantias sobre quais objetos vai chamar Dispose em que outros objetos; pode acontecer às vezes, mas você não deve se preocupar. Em vez disso, é sua responsabilidade para se certificar de Dispose () é chamado para todos os objetos IDisposable. A melhor maneira de fazer isso é com a declaração using. Por exemplo:

using (SqlDataReader aReader = aCommand.ExecuteReader())
{
    // your code
}

Concordo com todos os itens acima. Você deve certificar-se de que você chamar Dispose() mesmo, ea maneira mais fácil da isso é com a declaração using (você também pode fazer isso sozinho no bloco finally - este é mais detalhado, mas às vezes necessário). Se você não fizer isso, você pode encontrar o seu aplicativo vazamento de recursos não gerenciados, como alças, ou mesmo memória não gerenciada, especialmente se em algum lugar debaixo de tudo isso alguns componentes COM estão sendo usados, ou as chamadas estão sendo feitas na API Win32. Isso pode, obviamente, levar a problemas de desempenho e estabilidade, bem como o uso excessivo de recursos.

Apenas porque os objetos que implementam IDisposable "deve" implementar um finaliser que chama seu método Dispose(bool disposing) de recursos não gerenciados livres, há garantia de que isso vai acontecer, então você definitivamente não deve contar com ele. Veja, por exemplo, http://msdn.microsoft .com / en-us / library / b1yfkh5e% 28VS.71% 29.aspx para obter mais informações sobre este ponto.

Além disso, outra coisa a ter em mente, é que se o seu tipo tem membros que são descartáveis, seu tipo deve ou implementar IDisposable (a menos que o ciclo de vida desses membros é gerido por um outro tipo, o que obviamente pode ficar confuso), ou , se você só usa tais membros em um método, ou para implementar uma determinada peça de funcionalidade, você deve considerar o que os torna variáveis ??/ parâmetros locais nos métodos que os utilizam.

Estou intrigado com a afirmação: "No último bloco, os objectos que são eliminados manualmente de são aqueles que são definidos no nível da classe." Por objetos definidos no nível da classe, você campos médios? Você provavelmente não deve ser a eliminação destes dentro de um método comum, porque, então, o tempo de vida dos campos é imprevisível, e depende de quais métodos você passou a ter chamado. Seria melhor para implementar IDisposable e dispor de campos em seu método Dispose.

Poder Usando ajuda declaração ?

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top