Estou sendo solicitado a implementar IDisposable em objetos que são 100% recursos gerenciados, que não contêm fluxos e nem grandes recursos.

Eu entendo a importância de descartar adequadamente grandes recursos e recursos não gerenciados, mas e o outro lado da equação?

Para um objeto que não se beneficia da implementação de IDisposable (pequenos objetos totalmente gerenciados) , que impacto negativo GC.SuppressFinalize pode ter, se houver?

Comentários

  • Parece uma otimização prematura. Você está em posição de pedir à pessoa que lhe pediu para fazer isso os resultados que obteve com a criação de perfil e benchmarking que mostram que adicionar IDisposable neste caso melhora a pegada de memória?
  • @MainMa Não, mas isso não ' me impediu de perguntar de qualquer maneira. O resultado foi uma resposta de 5 minutos de " é apenas a maneira como ' sempre fizemos, você também faz ".
  • Bem, é possível implementar IDisposable sem escrever um destruidor / finalizador. Eu não ' não sei se a pessoa que pediu para você implementar IDisposable quis dizer que você deveria fazer um destruidor também. Obviamente, se a classe não tiver destruidor, não haverá nenhum ponto em GC.SuppressFinalize. Se a classe tiver um destruidor, certifique-se de dizer GC.SuppressFinalize(this) quando seu Dispose método for executado. Caso contrário, a instância não será coletada como lixo facilmente, ela será enfileirada em uma fila do finalizador e somente será coletada em uma coleta de geração 2.
  • @JeppeStigNielsen A questão afirma que os objetos estão lidando com gerenciamento totalmente recursos, então ' não há necessidade de ter um finalizador. Se houver um, sabemos que ' está errado.

Resposta

O único objetivo de GC.SuppressFinalize é:

evitar que o finalizador libere recursos não gerenciados que já foram liberados pela implementação IDisposable.Dispose.

Fonte: MSDN

Depois de descartar o objeto, você deve chamar GC.SuppressFinalize(this);, como mostrado em , uma resposta à pergunta ” Quando devo usar GC.SuppressFinalize ()? “. A análise de código “ regra CA1816 também é útil.

Agora, implementando IDisposable em objetos que não possuem recursos não gerenciados parecem bastante estranhos e questionáveis. Já que o único motivo que a pessoa deu a você foi: “é apenas a maneira que” sempre fizemos, você também faz “, em vez de fornecer dados de perfil / benchmarking que mostram que adicionar IDisposable vai melhorar algo em um caso específico, não há motivos reais para fazer isso.

Isso causaria problemas de desempenho? É difícil dizer: dependeria de um caso específico.

Seria causa algum outro problema? Claro. Sem contar o fato de que IDisposable é difícil de implementar, se essa prática for usada demais, o código se torna ilegível e impossível de manter:

public int ComputePrice(Rebate rebate) { using (var currentCurrency = this.User.FindCurrency()) { using (var priceWithoutRebate = this.GetPurePrice()) { using (var canApplyRebate = rebate.CanApplyTo(this)) { if (!canApplyRebate) { return priceWithoutRebate; } using (var priceWithRebate = priceWithoutRebate.Apply(rebate)) { return priceWithRebate; } } } } } 

Comentários

  • Bem, eu acredito que a história é que há muito tempo eles tinham alguma conexão / problemas de vazamento de stream, provavelmente devido ao código ADO.NET de comando / conexão com vazamento, e isso causou vazamentos de recursos massivos. Eles sabiam que implementar IDisposable em tudo resolveria o problema, então resolveram e funcionou. E agora eles j Basta implementá-lo na maioria dos objetos.
  • @AndrewHoffman: parece uma explicação plausível. Mas ainda não ' não justifica a prática atual.

Resposta

Você não precisa usar o padrão de peso pesado (“doloroso”) Descartar + Finalizador em uma classe IDisposable, if a classe está selada e não tem recursos não gerenciados.

Nessa situação, você pode usar um subconjunto do padrão Dispose + Finalizer, que tem apenas Dispose(), não tem finalizador e a classe está selada.

O motivo para selar a classe é evitar os problemas de “E se uma classe filha tiver recursos não gerenciados?” e “E se uma classe filha no futuro tiver recursos não gerenciados?”

Joe Duffy, anteriormente da Microsoft, tem um artigo longo (mais de 30 páginas) que discute como implementar corretamente IDisposable, e todas as implementações de subconjunto de permutação.

Os contribuintes do artigo incluem Herb Sutter, Brian Grunkemeyer, Jeff Richter e outros luminares do C #. O artigo é muito mais detalhado do que o apresentado no MSDN.

Infelizmente, o novo mecanismo de blog de Joe Duffy não fez um bom trabalho em preservar o artigo original de 2005, por isso parece um tanto mungido. Aqui está o link: http://joeduffyblog.com/2005/04/08/dg-update-dispose-finalization-and-resource-management/

Eu gostaria de poder anexar meu documento MS-Word que contém todo o artigo de Joe Duffy de uma forma muito melhor formato. 🙁

Deixe uma resposta

O seu endereço de email não será publicado. Campos obrigatórios marcados com *