Pregunta

¿El recolector de basura liberaría automáticamente el recursos no administrados (lo que sea, en realidad) asociado con algunos IDisposable ejemplo si, por ejemplo, me olvidé de escribir using ¿declaración?

Obviamente no lo sé cuando esto sucederia, pero ¿está bien dejar el IDisposable hacia GC cuando no me importan esos recursos y estoy de acuerdo con eso, serán eliminados eventualmente?

¿Fue útil?

Solución

¿Podría el recolector de basura libera automáticamente los recursos no administrados (lo que sea, en realidad) asociados con un cierto caso IDisposable si, por ejemplo, me había olvidado de escribir using?

Por lo general, pero no necesariamente. El autor de unas necesidades de recursos desechables para hacer lo correcto.

Obviamente, no sé cuando esto iba a pasar, pero ¿es bien dejar el IDisposable al GC cuando no me importa acerca de esos recursos y estoy bien con que van a ser eliminados con el tiempo?

Su pregunta presupone una falsedad. El recolector de basura nunca llama a botar, nunca. Por el contrario, el recolector de basura de la llama destructor (o "finalizador" si lo prefiere). Es el destructor, que podría o no podría llamar a Dispose para el usuario olvidadizo.

Su pregunta también indica una mala actitud. puede que no importa si los recursos son liberados tarde, pero sin duda otro programa podría cuidar! ¿Qué pasa si su cliente está ejecutando dos programas que ambos intentan tener acceso al mismo recurso no administrado, uno escrito por ti y otro escrito por otra persona? Ser un buen ciudadano; liberar sus recursos escasos tan pronto como haya terminado con ellos para que otros programas puedan usarlos Ese es el propósito real de "utilizar" -.. es ser educado, garantizando que los recursos escasos se recuperan rápidamente

Una aplicación correcta del patrón Desechar se asegurará de que el destructor limpia los recursos no administrados si los olvida de usuario para llamar a botar, y se asegurará de que el destructor no limpia los recursos si se acuerdan.

Si usted es la persona que escribe la aplicación de botar para una clase que posee los recursos no administrados es su responsabilidad para obtener el derecho de código destructor para el caso en que el usuario no llama Desechar correctamente. La forma correcta de escribir el código está muy bien documentada; siga el patrón. Ver los comentarios de Jon para algunos enlaces útiles.

Tenga en cuenta también que si usted está escribiendo una clase tan a continuación, se le requiere para también hacer que funcione en escenarios en los que es imposible para el usuario para llamar a Dispose. Por ejemplo, supongamos que el constructor asigna dos recursos no administrados, y entre la asignación de la primera y la segunda, se produce una excepción y atrapó fuera del constructor. Hay entonces no hay manera para que el usuario nunca llamar a Dispose ya que la asignación de la nueva referencia de objeto sucede después del constructor se ejecuta correctamente, y el constructor nunca terminó funcionando con éxito. ¿Cómo se libera el primer recurso no administrado? Sólo el destructor puede liberarla. El destructor tiene que ser robusta en la cara de tales escenarios; el objeto destruido nunca podría haber sido totalmente construido de manera que no se puede confiar en ninguna invariante del constructor.

Otros consejos

Sí, sería limpiado con el tiempo. Sólo es necesario el uso using (je ..) cuando se necesita la limpieza determinista de recursos, como por GDI, SQL y otras código basado en la manija del sistema o de los objetos potencialmente memoria pesada como DataTable.

Editar:. Esto es suponiendo que el derecho aplicado patrón Dispose y tener su Dispose llamada al destructor

Si un implementos de objetos de la interfaz IDisposable correctamente, mediante la inclusión de una llamada condicional al método Dispose en el finalizador, entonces el GC se disparará disposición del objeto durante una colección (a través del finalizador).

Hay cosas que causa esto no suceda, pero si se sigue el patrón estándar, entonces debería funcionar en la mayoría de los casos.

Si el objeto no incluye Código de basura en el finalizador, todas las apuestas están apagadas. Los recursos no administrados pueden permanecer no vendida hasta que las supernovas de sol.

No, no necesariamente.Depende de cómo tengas los recursos no administrados.

Si tienes un mango directo a los recursos no administrados (probablemente un IntPtr) entonces deberías tener un finalizador o usar SafeHandle...de lo contrario definitivamente podría perder recursos no administrados.

Si su tipo solo tiene una referencia a algo como un FileStream, entonces deberías esperar que eso El tipo tendrá un finalizador.

Ahora es bastante raro necesitar acceso directo a recursos no administrados desde su tipo, y si está utilizando tipos de marco, realmente deberían limpiarse adecuadamente (pero de manera no determinista).Aún así, es posible.

Cualquier IDisposable en las bibliotecas del sistema dispondrá sí mismo cuando finalizado (o al menos, se llevará a la mayor parte de los mismos pasos que desechar haría).

No hay ninguna garantía de cosas de terceros - si está utilizando una interfaz a alguna biblioteca C que le da mangos, por ejemplo, los tiradores no pueden ser limpiados hasta que se descarga la biblioteca (que sólo tiende a ocurrir en la salida aplicación). Pero es bastante común que se olvide de uso Dispose o using (o ni siquiera sabe ni le importa que un cierto tipo es desechable), que cualquier biblioteca .NET que no tuvo en cuenta que está bastante mal escrito, la OMI.

Cuando se crea un objeto, si se anula Object.Finalize, el sistema añadirá a una lista de objetos con finalizadores registrados. Los objetos de la lista, y los objetos referenciados directa o indirectamente por ellos, no serán elegibles para la eliminación a menos o hasta que GC.SuppressFinalize se llama en ellos, o que de otro modo se eliminan de la lista. Si los avisos del sistema que tal un objeto sería elegible para la eliminación pero para su existencia de la lista de objetos finalizables , el sistema eliminará si en la lista de objetos con finalizadores registrados y añadirlo a una lista de los objetos que deben tener su rutina Finalizar llamada tan pronto como sea conveniente. Siempre que esta última lista no está vacía, el sistema ejecuta las rutinas de Finalizar los objetos allí.

Tenga en cuenta que el recolector de basura no hace realmente nada Desechar - lo único que hace es llamar a la rutina de Finalización de objetos que se han registrado para la finalización. Aunque muchos tipos de objetos tienen rutinas Finalizar los que pueden asegurar la limpieza a los abandonados injustamente, la finalización puede ser lleno de peligros. Objetos rara vez se finalizará en el momento justo; que van a menudo no se finalizará hasta mucho después de que han sido abandonados, y en algunos casos pueden ser finalizados , mientras que sus recursos están todavía en uso . Por lo tanto es aconsejable evitar depender de los finalizadores. Hay algunas ocasiones en las que es necesaria, pero son casi siempre repulsivo.

Por cierto, cabe destacar que si los objetos de una determinada clase suscribirse directamente a eventos de objetos con una vida útil más larga, ni los antiguos objetos (suscriptores de eventos), ni ningún objeto a los que tienen referencias directas o indirectas, será elegible para eliminación o finalización hasta que los últimos objetos hacen. Aunque se podría argumentar que todas las clases deben limpiar después de sí mismos si son abandonados, lo que garantiza que un suscriptor de eventos puede descubrir que ha sido abandonado requiere la creación y el uso de objetos que los contienen. Esto añade una complejidad considerable y el rendimiento deterioran en el caso en que se utiliza la clase correctamente. Tratando de limpiar los eventos con un finalizador cuando no utilice objetos envolventes no tendría sentido; la clase de acontecimientos que cuelgan no sería elegible para la recolección hasta que el editor evento se convirtió en elegible, y una vez que eso ocurría no importaría si la clase anterior dado de baja o no.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top