¿Para qué es IDisposable?

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

La recolección de basura es para la memoria. Necesita deshacerse de los recursos que no son de memoria: identificadores de archivos, sockets, identificadores GDI +, conexiones de bases de datos, etc. Normalmente, eso es lo que subyace en un tipo IDisposable , aunque el identificador real puede ser bastante largo en una cadena de referencias. Por ejemplo, puede XmlWriter un XmlWriter que dispone de un StreamWriter que hace referencia, que dispone del FileStream que hace referencia, que libera el manejador del archivo.

Expandiendo un poco en otros comentarios:

El método Dispose () debe invocarse en todos los objetos que tienen referencias a recursos no gestionados. Ejemplos de esto incluirían flujos de archivos, conexiones a bases de datos, etc. Una regla básica que funciona la mayoría de las veces es: “si el objeto .NET implementa IDisposable, debe llamar a Dispose () cuando haya terminado con el objeto.

Sin embargo, algunas otras cosas a tener en cuenta:

  • Llamar a disponer no le da control sobre cuándo el objeto realmente se destruye y se libera la memoria. GC maneja eso para nosotros y lo hace mejor que nosotros.
  • Dispose limpia todos los recursos nativos, a lo largo de la stack de clases base como Jon indicó. Luego llama a SuprimirFinalizar () 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, GC considera que el objeto necesita limpieza, pero se debe llamar a Finalize primero, para asegurarse de que se liberan los recursos, que la solicitud de Finalize se pone en cola y el GC se mueve, por lo que la falta de llame a Dispose fuerzas para ejecutar un GC más antes de que el objeto se pueda limpiar. 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 memoria presionada, la promoción de objetos hasta generaciones más altas de GC puede empujar una aplicación de memoria alta a través de la pared a una aplicación sin memoria.
  • No implemente IDisposable en sus propios objetos a menos que sea absolutamente necesario. Las implementaciones mal implementadas o innecesarias en realidad pueden empeorar las cosas en lugar de mejorarlas. Alguna buena guía se puede encontrar aquí:

    Implementando un método de eliminación

    O lea toda la sección de MSDN en Garbage Collection

Porque los objetos en algún momento contienen recursos al lado de la memoria. GC libera la memoria; IDisposable es para que pueda lanzar cualquier otra cosa.

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

Ver, GC funciona, pero lo hace cuando así lo desee, e incluso entonces, los finalizadores que agregue a sus objetos serán llamados solo después de 2 recolecciones de GC. A veces, quieres limpiar esos objetos inmediatamente.

Esto es cuando se usa IDisposable. Llamando a Dispose () explícitamente (o usando el azúcar sintáctico de un bloque de uso) puede acceder a su objeto para limpiarse de una manera estándar (es decir, podría haber implementado su propia llamada de limpieza () y haberlo llamado explícitamente en su lugar)

Los recursos de ejemplo que desea limpiar de inmediato son: identificadores de bases de datos, manejadores de archivos, identificadores de red.

Para usar la palabra clave using, el objeto debe implementar IDisposable. http://msdn.microsoft.com/en-us/library/yh598w02(VS.71).aspx

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

Algunos objetos necesitan solicitar a 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 pedirle 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 para la entidad externa estará ligada a la necesidad del código externo para el objeto. Una vez que el código del cliente haya hecho todo lo que va a hacer con el objeto de flujo de archivos anteriormente mencionado, por ejemplo, ese objeto ya no necesitará tener acceso exclusivo (o cualquier acceso para el caso) a su 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 que el cliente de X pueda necesitar los servicios de X. El objective de IDisposable es proporcionar una forma uniforme de IDisposable a los objetos que sus servicios ya no serán necesarios, para que puedan notificar a las entidades (si las hay) que actuaban en su nombre que sus servicios ya no son necesarios. El código que llama IDisposable no necesita conocer 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 obligaciones (si corresponde) 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 (normalmente, aunque no necesariamente, otorgando el uso exclusivo de algo) hasta nuevo aviso, y libera un recurso cuando le dice a esa entidad externa que sus servicios ya no son necesarios. El código que adquiere un recurso no gana una “cosa” tanto como incurre en una obligación; liberar un recurso no renuncia a una “cosa”, sino que cumple una obligación.