2010-03-17 15 views
11

Viniendo de C/C++ hace mucho tiempo, todavía tengo la costumbre de asegurar que todos los recursos se limpien correctamente. Siempre me aseguro de que se usa Dispose en las clases IDisposable e implemento los patrones Dispose en mis clases que contienen objetos desechables.IDisposable, ¿realmente importa

Sin embargo, en mi entorno soy más o menos el único que hace esto. Otros simplemente no entienden lo que estoy haciendo y piensan que mi código es más difícil de entender.

Simplemente crean conexiones de bases de datos, abren secuencias, etc. sin llamar a Cerrar o Eliminar. A veces establecen una variable local o miembro a "Nothing" al final de un método (adivinar su fondo).

Mi problema es que su código funciona tan bien como el mío. El código que con el tiempo crea miles de objetos de conexión de base de datos simplemente funciona.

Por lo tanto, haciendo caso omiso de los argumentos sobre la corrección de los códigos, siguiendo las pautas, etc., hace IDiposable realmente importa?

¿Alguien realmente se ha quedado sin recursos de objetos que no se deshacen?

Edit: Gracias por todas las respuestas. Es interesante ver que algunas personas han tenido problemas cuando no se deshacen. Sin embargo, parece ser raro y supongo que el GC/JIT hace un buen trabajo para mantener el uso de recursos bajo condiciones normales.

Ni mis colegas ni yo cambiaremos el comportamiento debido a esto, pero se siente bien tener razón.

+1

Muchos problemas en SO son de la variedad "cosas raras sucede". Encuentro que aproximadamente la mitad de ellos se deben a la falta de eliminación, especialmente si solo ocurren la segunda o posteriores veces a través de un ciclo de algún tipo. La otra mitad son excepciones no controladas, por cierto. –

+0

He hecho la misma discusión con otros para usar el patrón IDisposible y he recibido una reacción similar. Ciertamente no estás solo en este conflicto. Le imploro que no comprometa lo que sabe que es correcto y apropiado porque su código es "difícil de leer". Solo mis 2 centavos. –

+2

si nada más, __explicit__ siempre es mejor que implícito independientemente del idioma –

Respuesta

26

Sí, he llegado al límite del número de cursores de Oracle al hacer un bucle sobre un objeto de conexión, por ejemplo, porque olvidé cerrar el lector de comandos; eso era solo 100 loops en una sola conexión, y necesitaba apoyar eso con posiblemente cientos de conexiones haciéndolo al mismo tiempo.

Se debe enseñar a los desarrolladores que usen el using() { ... } syntax si no se les puede molestar en cerrar ninguno de los recursos no administrados. De todos modos, es una buena práctica y también debe usarla, ya que usted mismo puede olvidarse de realizar sus llamadas Dispose() en una cláusula finally {} para poder realizar una verdadera limpieza en caso de que se produzca una excepción no controlada.

Si no puede conquistar sus corazones, cambie de opinión, cree pruebas que rompan su código maximizando los recursos que no están limpiando y luego demuestre que la "solución" es simple y fácil, y permite que su código sea mucho más escalable. O simplemente muéstralo a tu jefe y dile que esto le permitirá vender el producto como una nueva versión con más escalabilidad incorporada :) Tus compañeros desarrolladores recibirán instrucciones para hacer esto todo el tiempo en el futuro, con suerte, y serás tenido en mayor consideración también.

+4

+1 para escribir pruebas para romper malas prácticas. –

1

No desechar (o cerrar) las conexiones de la base de datos eventualmente lo morderán, sí. He visto que eso suceda.

+0

@ Anon-Downvoter "¿Alguien se ha quedado sin recursos de objetos no desechables?" Mi respuesta es una respuesta directa a esta pregunta que no requiere un ensayo, al menos explique su razonamiento defectuoso. – heisenberg

4

Algunos de estos recursos como los identificadores son un recurso limitado para todo el sistema, por lo que si su aplicación no lanza estas otras aplicaciones o incluso el sistema operativo puede sufrir. Eche un vistazo a Mark Russinovich's latest article en el límite de las series de Windows para ver ejemplos.

0

Tuve un caso del que desafortunadamente no recuerdo los detalles, pero era un tipo de secuencias en capas.La secuencia de archivos de nivel inferior a veces se cerró antes de que se descargara el formateador de texto de nivel superior, lo que provocó que se perdiera la última salida escrita en el formateador de texto.

3

Sí, también tuve un problema con los objetos de conexión a una base de datos Oracle que no se eliminó.

El problema anterior de Mike Atlas es malo, pero al menos estaba claro sobre lo que estaba pasando mal. El problema con el que nos topamos fue que, de vez en cuando, bajo mucha carga, el sitio comenzaba a arrojar errores cuando intentábamos abrir una conexión, pero cuando miramos el sistema todo se había aclarado (porque el cobrador de garabe había despejado los objetos y liberado el grupo de conexión). Fue muy difícil de reproducir, hasta que estuve revisando el código y noté que una conexión no se cerraba en caso de error, al cambiar esto a una declaración using se solucionó todo el problema.

La respuesta breve es que si un objeto toma el esfuerzo de implementar IDisposable, está ahí por alguna razón, por lo que SIEMPRE deseche cuando haya terminado, idealmente con una declaración using. No seas astuto o tramposo con la eliminación a veces, pero no en otras ocasiones cuando no creas que debes bla, bla, bla. Solo haz lo que funciona todo el tiempo.

La respuesta más breve y más satisfactoria es que tiene razón, y sus compañeros de trabajo son imbéciles que no saben lo que están haciendo.

5

Sí, es importante. Cuando un objeto implementa IDisposable, es explícitamente indicando que contiene recursos que deben liberarse cuando el objeto ya no se necesita.

La mayoría todavía limpiará sus recursos cuando el objeto esté finalizado, pero la finalización no es determinista y no se puede confiar en la administración de recursos.

Simplemente envolviendo las declaraciones de variables en un bloque using(...) hace que sea fácil deshacerse de ellas correctamente.

0

No deshacerse de la base de datos relajada Los objetos identificables son una forma confiable y eficiente de generar OutOfMemoryExceptions en entornos.

DataSet implementa IDisposable y he leído que no es necesario llamar a Dispose porque los objetos que deben desecharse para un conjunto de datos solo se crean en el momento del diseño (por el diseñador visual del estudio). Nunca he visto OOM a partir de datasets no expuestos (solo OOM de enormes DataSets)

0

Además de los casos obvios (ya mencionados) de recursos que se están acabando, otro beneficio de IDisposable es que, ya que garantiza que Dispose() es se llama cuando sale un bloque using, puede usarlo para todo tipo de cosas, incluso cosas que no son solo "realizar operaciones con el recurso del sistema operativo".

De esta manera, es como un sustituto de los pobres para los bloques Ruby, o para un caso de uso pequeño de las macros Lisp.

0

Sí, sí, sí, Importa.

He estado perfilando una aplicación recientemente que nunca se había perfilado. Es solo una aplicación de Winforms, no es gran cosa, ¿verdad?

Wrong.

Al no implementar controladores de eventos IDisposible y no de referencia, la aplicación goteaba la memoria como un tamiz.

.NET Framework no lo absuelve de limpiar después de usted mismo, solo hace que sea menos probable que rompa algo si no lo hace.

Pase una hora, perfile su aplicación con el ANTS Profiler. Es una prueba gratuita. Si no ve ninguna pérdida de memoria, continúe su camino. Si lo haces, es porque confiabas en .NET Framework para ser tu muleta.

+0

Conozco la teoría, pero ¿hay realmente problemas de memoria en el escritorio? (las aplicaciones de servidor son una cuestión diferente) Con gigabytes de memoria RAM disponibles, tomará un largo tiempo antes de que afecte el rendimiento. – adrianm

+1

Sí, importa. Si tiene una aplicación de escritorio de formularios múltiples que no está descartada, los datos que tiene también se mantienen vivos. Todo lo que tiene que hacer el usuario es usar su aplicación para que sea cada vez más lenta a medida que se activa y desactiva la memoria del disco. Si no le importa su solicitud, está bien. Solo dígame cuál es, así que no lo compro. –

Cuestiones relacionadas