DataSet y DataTable implementan IDisposable, por lo que, según las mejores prácticas convencionales, debería llamar a sus métodos Dispose ().
Sin embargo, por lo que he leído hasta ahora, DataSet y DataTable en realidad no tienen recursos no administrados, por lo que Dispose () en realidad no hace mucho.
Además, no puedo usar using(DataSet myDataSet...)
porque DataSet tiene una colección de DataTables.
Entonces, para estar seguro, necesitaría iterar a través de myDataSet.Tables, desechar cada una de las DataTables y luego desechar el DataSet.
Entonces, ¿vale la pena llamar a Dispose () en todos mis DataSets y DataTables?
Apéndice:
Para aquellos de ustedes que piensan que DataSet debe eliminarse: en general, el patrón para eliminar es usar using
o try..finally
, porque desean garantizar que se llamará a Dispose ().
Sin embargo, esto se pone feo muy rápido para una colección. Por ejemplo, ¿qué haces si una de las llamadas a Dispose () arrojó una excepción? ¿Se lo traga (que es "malo") para que pueda continuar para deshacerse del siguiente elemento?
¿O sugiere que simplemente llame a myDataSet.Dispose () y me olvide de deshacerme de las DataTables en myDataSet.Tables?
Respuestas:
Aquí hay un par de discusiones que explican por qué Dispose no es necesario para un DataSet.
¿Eliminar o no eliminar? :
¿Debería llamarse a Dispose en los objetos DataTable y DataSet? incluye alguna explicación de un MVP:
¿Comprender el método de eliminación y los conjuntos de datos? tiene un comentario de la autoridad Scott Allen:
Entonces, el consenso es que actualmente no hay una buena razón para llamar a Dispose en un DataSet.
fuente
using
bloque, depende de usted.Actualización (1 de diciembre de 2009):
Me gustaría enmendar esta respuesta y reconocer que la respuesta original era defectuosa.
El análisis original no se aplica a los objetos que requieren finalización - y el punto de que las prácticas no deben ser aceptados en la superficie sin una precisa, la comprensión en profundidad sigue en pie.
Sin embargo, resulta que DataSets, DataViews, DataTables suprimen la finalización en sus constructores ; es por eso que llamar a Dispose () en ellos explícitamente no hace nada.
Presumiblemente, esto sucede porque no tienen recursos no administrados; así que a pesar de que MarshalByValueComponent tiene en cuenta los recursos no administrados, estas implementaciones particulares no tienen la necesidad y, por lo tanto, pueden renunciar a la finalización.
(Que los autores de .NET se encargarían de suprimir la finalización en los tipos que normalmente ocupan más memoria habla de la importancia de esta práctica en general para los tipos finalizables).
No obstante, que estos detalles aún están poco documentados desde el inicio de .NET Framework (hace casi 8 años) es bastante sorprendente (que esencialmente se le deja a sus propios dispositivos para tamizar material aunque conflictivo y ambiguo para juntar las piezas). a veces es frustrante, pero proporciona una comprensión más completa del marco en el que confiamos todos los días).
Después de mucha lectura, aquí está mi entendimiento:
Si un objeto requiere finalización, podría ocupar la memoria más de lo necesario; he aquí por qué: a) Cualquier tipo que define un destructor (o hereda de un tipo que define un destructor) se considera finalizable; b) En la asignación (antes de que se ejecute el constructor), se coloca un puntero en la cola de Finalización; c) Un objeto finalizable normalmente requiere que se reclamen 2 colecciones (en lugar del estándar 1); d) La supresión de la finalización no elimina un objeto de la cola de finalización (según lo informado por! FinalizeQueue en SOS) Este comando es engañoso; Saber qué objetos están en la cola de finalización (en sí mismo) no es útil; Sería útil saber qué objetos están en la cola de finalización y aún requieren finalización (¿hay un comando para esto?)
Suprimir la finalización se apaga un poco en el encabezado del objeto, lo que indica al tiempo de ejecución que no necesita que se invoque su Finalizador (no es necesario mover la cola FReachable); Permanece en la cola de Finalización (y continúa siendo informado por! FinalizeQueue en SOS)
Las clases DataTable, DataSet, DataView están todas enraizadas en MarshalByValueComponent, un objeto finalizable que puede (potencialmente) manejar recursos no administrados
4 (nuevas referencias):
Respuesta original
Hay muchas respuestas engañosas y generalmente muy pobres sobre esto: cualquiera que haya aterrizado aquí debe ignorar el ruido y leer cuidadosamente las referencias a continuación.
Sin lugar a dudas, Dispose se debe invocar en cualquier objeto Finalizable.
Las tablas de datos son finalizables.
Calling Dispose acelera significativamente la recuperación de memoria.
MarshalByValueComponent llama a GC.SuppressFinalize (this) en su Dispose (); omitir esto significa tener que esperar docenas, si no cientos de colecciones Gen0 antes de recuperar la memoria:
Tómelo de alguien que ha visto cientos de MB de tablas de datos no referenciadas en Gen2: esto es muy importante y las respuestas en este hilo lo han perdido por completo.
Referencias
1 - http://msdn.microsoft.com/en-us/library/ms973837.aspx
2 - http://vineetgupta.spaces.live.com/blog/cns!8DE4BDC896BEE1AD!1104.entry http://www.dotnetfunda.com/articles/article524-net-best-practice-no-2-improve-garbage -collector-performance-using-finalizedispose-pattern.aspx
3 - http://codeidol.com/csharp/net-framework/Inside-the-CLR/Automatic-Memory-Management/
fuente
TableAdapter
s?Debe asumir que hace algo útil y llamar a Dispose incluso si no hace nada en corriente. Encarnaciones de NET Framework, no hay garantía de que se mantenga así en futuras versiones que conduzcan a un uso ineficiente de los recursos.
fuente
DataTable
no está sellado: no es un gran problema cuando lo estás haciendonew DataTable
, pero es muy importante cuando tomasDataTable
un argumento o como resultado de una llamada a un método.Incluso si el objeto no tiene recursos no administrados, la eliminación podría ayudar a GC al romper los gráficos de los objetos. En general, si el objeto implementa IDisposable, se debe llamar a Dispose ().
Si Dispose () realmente hace algo o no depende de la clase dada. En el caso de DataSet, la implementación Dispose () se hereda de MarshalByValueComponent. Se elimina del contenedor y llama al evento Disposed. El código fuente está debajo (desmontado con .NET Reflector):
fuente
¿Crea usted las tablas de datos usted mismo? Debido a que iterar a través de los elementos secundarios de cualquier objeto (como en DataSet.Tables) generalmente no es necesario, ya que es el trabajo del padre eliminar todos sus miembros secundarios.
En general, la regla es: si lo creó e implementa IDisposable, deséchelo. Si NO lo creó, NO lo deseche, ese es el trabajo del objeto primario. Pero cada objeto puede tener reglas especiales, consulte la Documentación.
Para .net 3.5, dice explícitamente "Deséchelo cuando ya no lo use", así que eso es lo que haría.
fuente
Llamo a dispose cada vez que un objeto implementa IDisposeable. Está ahí por una razón.
Los conjuntos de datos pueden ser enormes cerdos de memoria. Cuanto antes se puedan marcar para la limpieza, mejor.
actualizar
Han pasado 5 años desde que respondí esta pregunta. Todavía estoy de acuerdo con mi respuesta. Si hay un método de eliminación, debe llamarse cuando haya terminado con el objeto. La interfaz IDispose se implementó por una razón.
fuente
Si su intención o el contexto de esta pregunta es realmente la recolección de basura, puede configurar los conjuntos de datos y las tablas de datos para que sean nulos explícitamente o usar la palabra clave usando y dejarlos fuera de alcance. Desechar no hace mucho como Tetraneutron lo dijo antes. GC recopilará objetos del conjunto de datos que ya no están referenciados y también aquellos que están fuera del alcance.
Realmente deseo que SO obligue a las personas a votar para escribir un comentario antes de votar negativamente la respuesta.
fuente
Los conjuntos de datos implementan IDisposable a través de MarshalByValueComponent, que implementa IDisposable. Dado que los conjuntos de datos se administran, no hay un beneficio real en la disposición de llamadas.
fuente
Intente usar la función Clear (). Me funciona muy bien para deshacerme.
fuente
fuente