type returns remarks example c# garbage-collection dispose idisposable

c# - returns - ¿Para qué es idóneo?



remarks c# (6)

Si .NET tiene recolección de basura, ¿por qué tiene que llamar explícitamente a IDisposable ?


Expandiendo un poco en otros comentarios:

El método Dispose () debe llamarse en todos los objetos que tienen referencias a recursos no administrados. Los ejemplos de esto incluirían secuencias de archivos, conexiones de base de datos, etc. Una regla básica que funciona la mayor parte del tiempo es: "si el objeto .NET se implementa como IDisponible, debe llamar a Dispose () cuando haya terminado con el objeto.

Sin embargo, algunas otras cosas a tener en cuenta:

  • La llamada a disposición no le da control sobre cuándo se destruye realmente el objeto y se libera la memoria. GC se encarga de eso por nosotros y lo hace mejor que nosotros.
  • Dispose limpia todos los recursos nativos, hasta el final de la pila de clases base como Jon indicó. Luego llama a SuppressFinalize () para indicar que el objeto está listo para ser reclamado y no se necesita más trabajo. La próxima ejecución del GC lo limpiará.
  • Si no se llama a Dispose, entonces GC encuentra que el objeto necesita ser limpiado, pero Finalize debe llamarse primero, para asegurarse de que se liberen los recursos, esa solicitud de Finalize se pone en cola y el GC se mueve, por lo que la falta de la llamada a Dispose obliga a que se ejecute un GC más antes de poder limpiar el objeto. Esto hace que el objeto sea promovido a la siguiente "generación" de GC. Esto puede no parecer un gran problema, pero en una aplicación con presión de memoria, la promoción de objetos hasta generaciones más altas de GC puede empujar una aplicación de memoria alta por la pared hasta convertirse en una aplicación de memoria insuficiente.
  • No implemente IDisposable en sus propios objetos a menos que sea absolutamente necesario. Implementaciones deficientes o innecesarias pueden empeorar las cosas en lugar de mejorarlas. Aquí se puede encontrar una buena guía:

    Implementando un Método de Disposición

    O lea toda la sección de MSDN en la recolección de basura


La interfaz IDisposable se describe a menudo en términos de recursos, pero la mayoría de estas descripciones no consideran realmente lo que realmente significa "recurso".

Algunos objetos deben pedir a las entidades externas que hagan algo en su nombre, en detrimento de otras entidades, hasta nuevo aviso. Por ejemplo, un objeto que abarca una secuencia de archivos puede necesitar pedir a un sistema de archivos (que puede estar en cualquier parte del universo conectado) que otorgue acceso exclusivo a un archivo. En muchos casos, la necesidad del objeto por la entidad externa estará vinculada a la necesidad del código por el código externo. Una vez que el código del cliente haya hecho todo lo que va a hacer con el objeto de flujo de archivos mencionado anteriormente, por ejemplo, ese objeto ya no necesitará tener acceso exclusivo (o cualquier acceso) al archivo asociado.

En general, un objeto X que le pide a una entidad que haga algo hasta nuevo aviso incurre en la obligación de entregar dicho aviso, pero no puede entregar dicho aviso siempre y cuando el cliente de X pueda necesitar los servicios de X. El propósito de IDisposable es proporcionar una manera uniforme de que los objetos sepan que sus servicios ya no serán necesarios, para que puedan notificar a las entidades (si las hay) que actuaron en su nombre que ya no se requieren sus servicios. El código que llama IDisposable no necesita saber ni preocuparse por los servicios (si los hay) que un objeto ha solicitado a entidades externas, ya que IDisposable simplemente invita a un objeto a cumplir con las obligaciones (si las hay) con entidades externas.

Para poner las cosas en términos de "recursos", un objeto adquiere un recurso cuando le pide a una entidad externa que haga algo en su nombre (por lo general, aunque no necesariamente, otorga el uso exclusivo de algo) hasta nuevo aviso, y libera un recurso cuando le dice a la entidad externa que sus servicios ya no son necesarios. El código que adquiere un recurso no gana una "cosa" sino que incurre en una obligación; liberar un recurso no cede una "cosa", sino que cumple una obligación.


La recolección de basura es para la memoria. IDisposable deshacerse de los recursos que no son de memoria: identificadores de archivos, sockets, identificadores de GDI +, conexiones de base de datos, etc. Esto suele ser lo que subyace a un tipo IDisposable , aunque el identificador real puede estar bastante lejos en una cadena de referencias. Por ejemplo, podría XmlWriter un XmlWriter que XmlWriter un StreamWriter que tiene una referencia, que descarta el FileStream que tiene una referencia, que libera el identificador del archivo.



Porque los objetos a veces tienen recursos al lado de la memoria. GC libera la memoria; IDisponible es para que puedas liberar cualquier otra cosa.


porque desea controlar cuándo se limpiarán los recursos de su objeto.

Mire, GC funciona, pero lo hace cuando le da la gana, e incluso entonces, los finalizadores que agregue a sus objetos serán llamados solo después de 2 colecciones de GC. A veces, quieres limpiar esos objetos inmediatamente.

Esto es cuando se utiliza IDisposable. Al llamar a Dispose () explícitamente (o al usar el azúcar sintáctico de un bloque que usa), puede obtener acceso a su objeto para limpiarse de forma estándar (es decir, podría haber implementado su propia llamada de limpieza () y haberlo llamado explícitamente)

Los recursos de ejemplo que desearía limpiar de inmediato son: identificadores de base de datos, identificadores de archivos, identificadores de red.