DataSet e DataTable implementam IDisposable, portanto, pelas práticas recomendadas convencionais, devo chamar seus métodos Dispose ().
No entanto, pelo que li até agora, o DataSet e o DataTable não possuem recursos não gerenciados, portanto Dispose () não faz muito.
Além disso, não posso usar apenas using(DataSet myDataSet...)
porque o DataSet possui uma coleção de DataTables.
Portanto, para estar seguro, eu precisaria percorrer myDataSet.Tables, descartar cada DataTables e descartar o DataSet.
Portanto, vale a pena chamar Dispose () em todos os meus DataSets e DataTables?
Termo aditivo:
Para aqueles que pensam que o DataSet deve ser descartado: Em geral, o padrão para descarte é usar using
ou try..finally
porque você deseja garantir que Dispose () será chamado.
No entanto, isso fica feio e rápido demais para uma coleção. Por exemplo, o que você faz se uma das chamadas para Dispose () lança uma exceção? Você o engole (que é "ruim") para poder continuar a descartar o próximo elemento?
Ou você sugere que eu chame apenas myDataSet.Dispose () e esqueça de descartar as DataTables em myDataSet.Tables?
Respostas:
Aqui estão algumas discussões explicando por que o Dispose não é necessário para um DataSet.
Dispor ou Não Dispor? :
Dispose deve ser chamado nos objetos DataTable e DataSet? inclui algumas explicações de um MVP:
Compreendendo o método Dispose e conjuntos de dados? tem um comentário da autoridade Scott Allen:
Portanto, existe um consenso de que atualmente não há um bom motivo para chamar Dispose em um DataSet.
fonte
using
bloco, é com você.Atualização (1 de dezembro de 2009):
Gostaria de alterar esta resposta e admitir que a resposta original foi falha.
A análise original se aplica a objetos que requerem finalização - e o ponto em que as práticas não devem ser aceitas na superfície sem um entendimento preciso e profundo ainda permanece.
No entanto, verifica-se que DataSets, DataViews, DataTables suprimem a finalização em seus construtores - é por isso que chamar Dispose () neles explicitamente não faz nada.
Presumivelmente, isso acontece porque eles não têm recursos não gerenciados; portanto, apesar do MarshalByValueComponent conceder permissões para recursos não gerenciados, essas implementações específicas não têm a necessidade e podem, portanto, renunciar à finalização.
(Que os autores do .NET cuidem de suprimir a finalização nos tipos que normalmente ocupam mais memória fala da importância dessa prática em geral para os tipos finalizáveis.)
Não obstante, esses detalhes ainda estão sub-documentados desde o início do .NET Framework (quase 8 anos atrás) é bastante surpreendente (que você é essencialmente deixado por seus próprios dispositivos para peneirar material ambíguo e conflitante para juntar as peças às vezes é frustrante, mas fornece uma compreensão mais completa da estrutura em que confiamos todos os dias).
Depois de muita leitura, aqui está o meu entendimento:
Se um objeto requer finalização, ele pode ocupar memória mais do que o necessário - eis o porquê: a) Qualquer tipo que define um destruidor (ou herda de um tipo que define um destruidor) é considerado finalizável; b) Na alocação (antes da execução do construtor), um ponteiro é colocado na fila de finalização; c) Um objeto finalizável normalmente exige que 2 coleções sejam recuperadas (em vez do padrão 1); d) Suprimir a finalização não remove um objeto da fila de finalização (conforme relatado por! FinalizeQueue no SOS) Este comando é enganoso; Saber quais objetos estão na fila de finalização (por si só) não é útil; Saber quais objetos estão na fila de finalização e ainda requerem finalização seria útil (existe um comando para isso?)
A supressão da finalização desativa um pouco no cabeçalho do objeto, indicando para o tempo de execução que ele não precisa ter seu Finalizer invocado (não precisa mover a fila FReachable); Ele permanece na fila de finalização (e continua a ser relatado por! FinalizeQueue no SOS)
As classes DataTable, DataSet, DataView estão todas enraizadas em MarshalByValueComponent, um objeto finalizável que pode (potencialmente) manipular recursos não gerenciados
4 (novas referências):
Resposta original:
Há muitas respostas enganosas e geralmente muito ruins sobre isso - quem chegou aqui deve ignorar o barulho e ler as referências abaixo com cuidado.
Sem dúvida, Dispose deve ser chamado em qualquer objeto Finalizável.
As tabelas de dados são finalizáveis.
Chamar Dispose acelera significativamente a recuperação da memória.
MarshalByValueComponent chama GC.SuppressFinalize (this) em seu Dispose () - pular isso significa ter que esperar dezenas, senão centenas, de coleções Gen0 antes que a memória seja recuperada:
Suponha que alguém que tenha visto centenas de MBs de DataTables não referenciados no Gen2: isso é extremamente importante e completamente esquecido pelas respostas neste tópico.
Referências:
1 - http://msdn.microsoft.com/en-us/library/ms973837.aspx
2 - http://vineetgupta.spaces.live.com/blog/cns!8DE4BDC896BEE1AD!1104.entry http://www.dotnetfunda.com/articles/article524-net-best-practice-no-2-improve-garbage -collector-performance-using-finalizedispose-pattern.aspx
3 - http://codeidol.com/csharp/net-framework/Inside-the-CLR/Automatic-Memory-Management/
fonte
TableAdapter
s?Você deve assumir que ele faz algo útil e chamar Dispose, mesmo que não faça nada na atualidade. Encarnações do NET Framework, não há garantia de que continuará assim em versões futuras, levando ao uso ineficiente de recursos.
fonte
DataTable
não está selado - não é grande coisa quando você está fazendonew DataTable
, mas é muito importante quando você aceita umDataTable
argumento ou como resultado de uma chamada de método.Mesmo que o objeto não tenha recursos não gerenciados, o descarte pode ajudar o GC quebrando os gráficos de objetos. Em geral, se o objeto implementa IDisposable, Dispose () deve ser chamado.
Se Dispose () realmente faz alguma coisa ou não depende de uma determinada classe. No caso de DataSet, a implementação Dispose () é herdada de MarshalByValueComponent. Ele se remove do contêiner e chama o evento Disposed. O código fonte está abaixo (desmontado com o .NET Reflector):
fonte
Você mesmo cria as DataTables? Como a iteração através dos filhos de qualquer Objeto (como no DataSet.Tables) geralmente não é necessária, pois é dever do pai descartar todos os seus membros filhos.
Geralmente, a regra é: Se você a criou e implementa IDisposable, Dispose it. Se você NÃO o criou, NÃO o descarte, esse é o trabalho do objeto pai. Mas cada objeto pode ter regras especiais, consulte a documentação.
Para o .net 3.5, ele diz explicitamente "Descarte-o quando não estiver mais em uso", e é isso que eu faria.
fonte
Chamo de disposição a qualquer momento que um objeto implementa IDisposeable. Está lá por uma razão.
Os conjuntos de dados podem ser grandes quantidades de memória. Quanto mais cedo eles forem marcados para limpeza, melhor.
atualizar
Faz cinco anos desde que eu respondi a essa pergunta. Eu ainda concordo com a minha resposta. Se houver um método de descarte, ele deverá ser chamado quando você terminar o objeto. A interface IDispose foi implementada por um motivo.
fonte
Se sua intenção ou o contexto desta pergunta for realmente uma coleta de lixo, você poderá definir os conjuntos de dados e tabelas de dados para nulos explicitamente ou usar a palavra-chave using e deixá-los fora do escopo. Dispose não faz muito como Tetraneutron disse anteriormente. O GC coletará objetos do conjunto de dados que não são mais referenciados e também aqueles que estão fora do escopo.
Eu realmente gostaria que as pessoas forçadas a votar a escrever um comentário antes de votar na resposta.
fonte
Os conjuntos de dados implementam MarshalByValueComponent completo com IDisposable, que implementa IDisposable. Como os conjuntos de dados são gerenciados, não há benefício real em chamar o descarte.
fonte
Tente usar a função Clear (). Funciona muito bem para mim para descartar.
fonte
fonte