2009-07-01 12 views
12

Utilizamos Enterprise Library 3.0 para acceder a Oracle DB (cliente de microsoft oracle). ¿Qué sucede cuando no dispongo de una instancia de DbCommand después de llamar a un procedimiento o función almacenados? ¿.NET recoge basura automáticamente? Tenga en cuenta que nos aseguramos de que la transacción/conexión se cierre y elimine correctamente.¿Es necesario desechar DbCommand después del uso?

Respuesta

17

Este es un duplicado, pero no tiene tiempo para encontrar el original.

Si implementa IDisposable, y si lo creó, debe llamar a Dispose en él. Es por eso que el desarrollador de la clase lo hizo implementar IDisposable.

El recolector de basura no llama a Dispose en todos los objetos implementables IDisposable.

+0

¿Qué? No, eso es falso. El patrón estándar para Dispose es permitir a los usuarios liberar los recursos antes de tiempo, pero aún limpiar en el finalizador si el método aún no se ha llamado. – RandomEngy

+0

Vea este artículo: http://msdn.microsoft.com/en-us/library/b1yfkh5e.aspx Se llama a Dispose() en el finalizador, que de hecho se ejecutará cuando el recolector de elementos no utilizados llegue a él. – RandomEngy

+4

No todos los usuarios de IDisposable implementan un finalizador. No todos los que implementan un finalizador seguirán el patrón estándar. No se puede depender de la existencia de un finalizador, y no se puede depender de que el recolector de basura se encargue de la eliminación. –

1

No es 100% seguro acerca de Oracle, pero cuando se utiliza SqlCommand, se debe eliminar después de su uso. Usted podría simplemente llamar .Dispose(), o simplemente ponerlo en un bloque usando, así:


using(DbCommand cmd = new DbCommand(foo, bar)) 
{ 
    // use cmd object 
} 
7

Reflector no indica que OracleCommand anule específicamente Disposición (de la implementación System.ComponentModel.Component, de todos modos), así que es probable que no le afecte mucho la aplicación si no la llama.

Lo importante, sin embargo, es que OracleCommand implementa específicamente IDbCommand, que implementa específicamente IDisposable. Si alguna vez reemplazó su OracleCommand con otra IDbCommand, lo más probable es que desee utilizar Dispose(). Y aunque SqlCommand no anula explícitamente Dispose(), Odbc y OleDb ciertamente lo hacen.

En resumen, ya que es IDisposable, debe desecharlo, solo para estar seguro.

+0

Gracias por la explicación. – Vivek

4

De la documentación para IDisposable:

El uso principal de esta interfaz es liberar recursos no administrados. El recolector de basura libera automáticamente la memoria asignada a un objeto administrado cuando ese objeto ya no se usa. Sin embargo, no es posible predecir cuándo ocurrirá la recolección de basura. Además, el recolector de basura no tiene conocimiento de los recursos no administrados, como los identificadores de ventanas o los archivos y las secuencias abiertos.

Utilice el método Dispose de esta interfaz para liberar explícitamente recursos no administrados junto con el recolector de elementos no utilizados. El consumidor de un objeto puede llamar a este método cuando el objeto ya no se necesita.

Teniendo en cuenta esto, un objeto que implementa IDisposable mantiene potencialmente referencias a recursos no administrados. Estos recursos no se liberan hasta que el recolector de basura aparece y recoge el objeto. Sin embargo, dado que no puede saber cuándo lo hará el recolector de elementos no utilizados, los objetos desechables (como OracleDbCommand) pueden permanecer mucho más tiempo de lo que pueda desear.

Si un objeto implementa IDisposable, debe llamarlo tan pronto como sea posible para liberar los recursos no administrados que contiene referencias. Esto se puede lograr llamando al Dispose directamente o declarándolo dentro de un bloque de uso.

+1

Lo leí para decir que "Además, el recolector de basura no tiene conocimiento de los recursos no administrados como los identificadores de ventanas o los archivos y las secuencias abiertos". Por lo tanto, el GC _no_ liberará estos recursos, nunca. –

+1

Es precisamente por eso que una clase implementa IDisposable. El GC no puede liberarlos porque no los conoce.La clase que contiene esos recursos no administrados debe liberarlos cuando se invoca el método Dispose. –

+0

Pero dijiste "Estos recursos no se liberan hasta que llega el recolector de basura y recoge el objeto". La liberación de estos recursos no administrados no depende, en general, del recolector de basura en absoluto. –

Cuestiones relacionadas