У меня есть DataGridView, который регулярно заполняется с помощью объектов, привязанных к данным, и количество строк потенциально может стать большим, скажем, многие тысячи во время «цикла регистрации».
Когда начинается новый «цикл регистрации», сетка очищается, потому что базовый источник данных очищается, и процесс начинается снова.
Это все хорошо, но поскольку предыдущий запуск занимает некоторое время, все эти предыдущие строки становятся объектами поколения 2, а только мусор собирается при полной сборке мусора.
Однако для их очистки требуется ДВА полных GC, потому что первый отправляет их все в очередь финализатора. Это означает, что они зависают в два раза дольше памяти.
Используя рефлектор, я вижу, что DataGridViewRow не имеет метода финализатора, но он наследуется от объекта DataGridViewBand, который делает это, и вызывает GC.SuppressFinalize(this) через его общедоступный метод Dispose().
Итак, мой вопрос: почему мои DataGridViewRows не собираются при первом полном сборщике мусора и не попадают в очередь финализатора в ожидании другого?
(Мои предположения здесь заключаются в том, что любой объект без финализатора не должен помещаться в очередь финализатора, и любой объект, у которого он есть, но вызывает GC.SuppressFinalize, также не будет помещен в очередь. Я прав в этом предположении?)
Спасибо.
DataGridViewRow
наследуется от финализируемого объекта, он фактически становится финализируемым объектом и помещается в очередь. То, что вы видите, верно. Скорее всего, методClear()
также не удаляет строки, и в этом случае вы можете вручную удалить их до (или после) вызоваClear()
, хотя я не уверен, что это возможно. (Это будет зависеть от того, как все реализовано.) При желании вы можете вызватьDispose()
для базового источника данных, что может работать. 07.10.2009Dispose()
. Это всего лишь одна из многих причин, по которым не следует делать объекты финализируемыми, если для этого нет весьма веской причины. 10.10.2009