Se me pide que implemente IDisposable en objetos que son 100% recursos administrados, que no contienen flujos ni grandes recursos.

Entiendo la importancia de disponer adecuadamente de grandes recursos y recursos no administrados, pero ¿qué pasa con el otro lado de la ecuación?

Para un objeto que no se beneficia de implementar IDisposable (pequeños objetos completamente administrados) , ¿qué impacto negativo puede tener GC.SuppressFinalize, si lo hubiera?

Comentarios

  • Parece una optimización prematura. ¿Está en condiciones de preguntarle a la persona que le pidió que lo hiciera los resultados que obtuvo de la elaboración de perfiles y la evaluación comparativa que muestran que agregar IDisposable en este caso mejora la huella de memoria?
  • @MainMa No, pero eso no ' me impidió preguntar de todos modos. El resultado fue una respuesta de 5 minutos de " es exactamente la forma en que ' siempre lo hemos hecho, tú también ".
  • Bueno, es posible implementar IDisposable sin escribir un destructor / finalizador. No ' sé si la persona que te pidió que implementaras IDisposable quiso decir que también debías hacer un destructor. Por supuesto, si la clase no tiene destructor, no tiene sentido GC.SuppressFinalize. Si la clase tiene un destructor, asegúrese de decir GC.SuppressFinalize(this) cuando se haya ejecutado su método Dispose. De lo contrario, la instancia no se recopilará fácilmente, se pondrá en cola en una cola de finalizador y solo se recopilará en una recopilación de generación 2.
  • @JeppeStigNielsen La pregunta indica que los objetos se tratan completamente administrados recursos, por lo que ' no es necesario tener un finalizador. Si hay uno, sabemos que ' está mal.

Responder

El único objetivo de GC.SuppressFinalize es:

evitar que el finalizador libere recursos no administrados que ya han sido liberados por la implementación IDisposable.Dispose.

Fuente: MSDN

Una vez que haya eliminado el objeto, debería llamar a GC.SuppressFinalize(this);, como se muestra en una respuesta a la pregunta » ¿Cuándo debería usar GC.SuppressFinalize ()? «. La regla de análisis de código « CA1816 también es útil.

Ahora, implementando IDisposable en los objetos que no tienen recursos no administrados se ven bastante raros y cuestionables. Dado que la única razón que le dio la persona fue: «es la forma en que» siempre lo hemos hecho, usted también lo hace «, en lugar de proporcionar datos de evaluación comparativa / perfiles que muestren que agregar IDisposable mejorará algo en un caso específico, no hay razones reales para hacerlo.

¿Causaría problemas de rendimiento? Difícil de decir: dependería del caso particular.

¿ ¿Causa algún otro problema? Por supuesto. Sin contar el hecho de que IDisposable es doloroso de implementar, si esta práctica se usa demasiado, el código se vuelve ilegible e imposible de mantener:

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; } } } } } 

Comentarios

  • Bueno, creo que la historia es que hace mucho tiempo, tenían alguna conexión / problemas de fugas de flujo, probablemente debido a una conexión / comando con fugas en el código ADO.NET, y esto causó fugas masivas de recursos. Sabían que implementar IDisposable en todo resolvería el problema, así que lo hicieron, y funcionó. Y ahora j Usemos para implementarlo en la mayoría de los objetos.
  • @AndrewHoffman: parece una explicación plausible. Pero todavía no ' justifica la práctica actual.

Respuesta

No es necesario que utilice el patrón Dispose + Finalizer pesado («doloroso») en una clase IDisposable, si la clase está sellada y la clase no tiene recursos no administrados.

En esa situación, puede usar un subconjunto del patrón Dispose + Finalizer, que solo tiene public Dispose(), no tiene finalizador y la clase está sellada.

La razón para sellar la clase es evitar los problemas de «¿Qué pasa si una clase secundaria tiene recursos no administrados?» y «¿Qué pasa si una clase secundaria en el futuro tendrá recursos no administrados?»

Joe Duffy, anteriormente de Microsoft, tiene un artículo extenso (más de 30 páginas) que analiza cómo implementar correctamente IDisposable, y todas las implementaciones de subconjuntos de permutación.

Los colaboradores del artículo incluyen a Herb Sutter, Brian Grunkemeyer, Jeff Richter y otras luminarias de C #. El artículo es mucho más detallado que lo que se presenta en MSDN.

Por desgracia, el nuevo motor de blogs de Joe Duffy no ha hecho un buen trabajo conservando el artículo original de 2005, por lo que parece un poco molesto. Aquí está el enlace: http://joeduffyblog.com/2005/04/08/dg-update-dispose-finalization-and-resource-management/

Me gustaría poder adjuntar mi documento de MS-Word que tiene la totalidad del artículo de Joe Duffy de una manera mucho mejor formato. 🙁

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *