2013-09-18 5 views
6

Я исследование через очень простой код и застревают увидав Dispose() результат DataTableDatatable.Dispose() удалит его из памяти?

Ниже приводится код

DataTable dt= new Datatable(); 
SqlCommand Cmd = new SqlCommand("sp_getData",SqlCon); 
SqlCommand.CommandType= CommandType.StroedProcedure; 
SqlCon.Open(); 
sqlDataReader dr= cmd.ExecuteReader(); 
dt.Load(dr); 
SqlCon.Close(); 
grdView.DataSource =dt; 
dt.Dispose() // Here I dispose the table as it is no use for me & wanna memory free from this 

Но настроив от в DataTable я еще нашел, что он все еще показывает RowCount = 10k.

Does Dispose() метод не освобождает память & сделать объект как null?

Как я могу сделать это как null или освободить память, занимаемую этим объектом?

ответ

14

DataSet и DataTable фактически не имеют никаких неуправляемых ресурсов, поэтому Dispose() фактически не делать.Методы Dispose() в DataSet и DataTable существуют ТОЛЬКО из-за побочного эффекта наследования - другими словами, он фактически не делает ничего полезного в финализации.

Оказывается, что DataSets, DataViews, DataTables подавляют финализации в их constructorsc поэтому называя Dispose() на них явно ничего не делает.

Предположительно, это происходит потому, что, как упоминалось выше, у них нет неуправляемых ресурсов; поэтому, несмотря на то, что MarshalByValueComponent делает скидку на неуправляемые ресурсы, эти конкретные реализации не нуждаются в этом и поэтому могут отказаться от завершения.

Обзор this Immense Answer:

Без сомнения, Dispose следует вызывать какие-либо финализируемые объекты.

Данные могут быть завершены.

Calling Dispose значительно ускоряет восстановление памяти.

MarshalByValueComponent называет GC.SuppressFinalize(this) в его Dispose() - пропуская это означает, что приходится ждать десятки, если не сотни Gen0 коллекций до памяти будет утилизирована.

Дополнительная литература:

См this question и связанное с ним answer.

+0

Спасибо, что ответ запутан. Каков вывод? – Tohid

+0

Обязательно вызовите 'Dispose()', но он ничего не делает. По сути, использование dispise на объектах не требуется. – MoonKnight

6
метод

ли Dispose() не освобождает косметику объекта памяти &, как нуля ??

Dispose и структура утилизации не для освоения управляемой памяти или «удаление» управляемые объекты (как вещи, которые вы не можете сделать и то, что сборщик мусора там), то для обработки удаления/освобождения неуправляемых ресурсов или другие управляемые ресурсы, которые имеют выпущенные элементы, такие как SqlConnection. Это конечно не будет null ссылкой, но может сделать его непригодным с момента удаления вперед.

Как я могу сделать это как null или освободить память, занимаемую этим объектом ??

Если вы хотите обнулить ссылку, просто dt = null будет работать, хотя это не даст вам никакой пользы, как экземпляр DataTable ссылается grdView.DataSource. Оба dt и grdView.DataSource будут ссылками на тот же базовый пример DataTable.

Я также подозреваю, что это часть метода, и в этом случае dt - метод в любом случае.

Вам не нужно слишком беспокоиться об этом. Меня больше беспокоит наличие SqlConnection за пределами try-finally/using, вы рискуете оставить там доступ.

Я, как правило, в пользу вызова Dispose по вопросам, которые реализуют IDisposable за то, что я думаю, что это очень хорошая причина: это публичный договор. Факт того, что вызов его делает что-либо или нет, представляет собой деталь реализации и является , подлежащий изменению в момент уведомления.


Как и в сторону, я бы полностью переписать код:

var dt = new Datatable(); 

using (var conn = new SqlConnection("")) 
using (var comm = new SqlCommand("sp_getData", conn)) 
{ 
    conn.Open(); 

    using (var reader = comm.ExecuteReader()) 
    { 
     dt.Load(reader); 
    } 
} 

grdView.DataSource = dt; 
+0

Если я сделаю это dt = null, gridview все еще преуспевает. Хорошая ли привычка сделать его нулевым и освободить память? –

+0

@Rajeev Я думаю, что это хорошая привычка вызывать 'Dispose' на элементах, которые вы закончили, однако вы присвоили' DataTable' 'DataSource', поэтому вы не хотите называть' Dispose', поскольку он не завершено. Явно обнуление элементов редко требуется. –

+0

Я не прошу о вызове метода Dispose() вместо того, чтобы сделать его нулевым, вызывая 'dt = null'. Gridview по-прежнему преуспевает в этом случае, и моя память также освобождается. –

0

Попробуйте использовать функцию Clear(). Это отлично работает для меня.

DataTable dt = GetDataSchema(); 
//populate dt, do whatever... 
dt.Clear(); 
Смежные вопросы