Следует ли мне Dispose() DataSet и DataTable?

Обновление (1 декабря 2009 г.):

Я хотел бы исправить этот datasets ответ и признать, что исходный dataset ответ был ошибочным.

Исходный dispose-pattern анализ действительно применим к объектам, требующим dispose доработки - и точка зрения, что disposal практики не должны приниматься dispose-pattern на поверхности без точного, глубокого datatable понимания. стоит.

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

Предположительно, это datasets происходит потому, что у datasets них нет неуправляемых ресурсов; поэтому, несмотря resource-disposal на то, что MarshalByValueComponent допускает использование dispose неуправляемых ресурсов, в idisposable этих конкретных реализациях datasets нет необходимости и поэтому datasets можно отказаться от завершения.

(То, что datatable авторы .NET позаботятся о dispose подавлении финализации тех disposing самых типов, которые обычно datatable занимают больше всего памяти, говорит dataset о важности этой практики dispose-pattern в целом для финализируемых datasets типов.)

Несмотря на то, что datasets эти детали все еще недостаточно resource-disposal документированы с момента disposing появления .NET Framework disposing (почти 8 лет назад), это disposing довольно удивительно (что disposal вы, по сути, предоставлены disposing своим собственным устройствам, чтобы dataset отсеивать, хотя и противоречивый, неоднозначный datasets материал для размещения иногда disposal это разочаровывает, но дает resource-disposal более полное представление datasets о структуре, на которую мы datatable полагаемся каждый день).

После disposal долгого чтения я понял:

Если disposing объект требует завершения, он datasets может занимать память дольше, чем datatable необходимо - вот почему: a) Любой resource-disposal тип, который определяет деструктор idisposable (или наследуется от типа resource-disposal который определяет деструктор) считается resource-disposal финализируемым; б) При выделении dataset (до запуска конструктора) указатель using помещается в очередь финализации; c) Для dispose финализируемого объекта обычно datatable требуется восстановить 2 коллекции (вместо disposing стандартной 1); г) Подавление disposing финализации не удаляет объект dispose-pattern из очереди финализации (как disposing сообщает! FinalizeQueue в resource-disposal SOS) Эта команда вводит в using заблуждение; Знание того, какие disposing объекты находятся в очереди datasets на завершение (само по себе), бесполезно; Было resource-disposal бы полезно знать, какие объекты idisposable находятся в очереди финализации datatable и по-прежнему требуют завершения datasets (есть ли для этого команда?)

Подавление dataset финализации немного отключается disposing в заголовке объекта, указывая disposing среде выполнения, что не datasets нужно вызывать ее Finalizer resource-disposal (не нужно перемещать очередь dataset FReachable); Он остается dispose-pattern в очереди финализации (и disposal о нем продолжает сообщать! FinalizeQueue dispose в SOS)

Все классы DataTable, DataSet, DataView datatable основаны на MarshalByValueComponent, финализируемом datatable объекте, который (потенциально) может disposal обрабатывать неуправляемые using ресурсы

  • Поскольку DataTable, DataSet, DataView не содержат неуправляемых ресурсов, они подавляют завершение в своих конструкторах.
  • Хотя это необычный шаблон, он освобождает вызывающего абонента от необходимости беспокоиться о вызове Dispose после использования.
  • Это, а также тот факт, что DataTables потенциально могут совместно использоваться разными DataSet, вероятно, почему DataSets не заботятся об удалении дочерних DataTables.
  • Это также означает, что эти объекты появятся в очереди! FinalizeQueue в SOS.
  • Однако эти объекты должны быть восстановлены после единственной коллекции, как и их незавершенные копии

4 (новые ссылки):

Исходный ответ:

Есть много вводящих using в заблуждение и, как правило, очень datasets плохих ответов по этому поводу using - любой, кто приземлился dispose-pattern здесь, должен игнорировать using шум и внимательно читать datatable ссылки ниже.

Без сомнения, Dispose datasets следует вызывать для любых объектов resource-disposal Finalizable.

Таблицы данных resource-disposal являются финализируемыми.

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

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

Исходя из этого базового disposal понимания процесса доработки, мы уже dispose могу вывести некоторые очень dataset важные вещи:

Во-первых, объекты, требующие dispose-pattern доработки. живут дольше, чем datasets предметы, которые этого не dispose-pattern делают. На самом деле они dataset могут жить намного дольше. Например, предположим, что dispose-pattern объект, который находится disposing в gen2, нуждается в доработке. Доработка disposing будет запланирована, но объект disposal все еще находится в gen2, поэтому disposing он будет не собираются dispose-pattern повторно до следующего сбор dispose-pattern gen2 происходит. Это могло datatable быть действительно очень idisposable долго, и, по сути, если datatable дела пойдут хорошо, это будет давно, потому dataset что коллекции gen2 дорогостоящие, и dispose поэтому мы хотим, чтобы они случаются datatable очень нечасто. Старшая объекты, требующие idisposable доработки, могут придется dataset ждать десятки, если нет сотни using коллекций gen0 до их пространство dispose-pattern освоено.

Во-вторых, объекты, требующие disposal доработки причинить побочный datatable ущерб. Поскольку указатели datasets на внутренние объекты должны dataset оставаться действителен, не datasets только объекты непосредственно disposing нуждающиеся в доработке задерживаются в datasets памяти, но все объект относится dispose-pattern прямо или косвенно к тоже idisposable останется в памяти. Если datatable огромный дерево объектов disposal было закреплено один объект, который datatable требовал доработка, потом datatable все дерево задержится потенциально datatable надолго время, как мы только dataset что обсуждали. это поэтому datasets важно использовать финализаторы экономно dispose-pattern и размещать их на предметах которые datatable имеют как можно меньше внутренних disposal объектов указатели по возможности. В disposing дереве пример, который datatable я только что привел, вы легко datatable можете избежать проблемы, переместив ресурсы, нуждающиеся datasets в доработке, в отдельный datatable объект и ведение ссылка dispose-pattern на этот объект в корне дерева. С idisposable этим скромным изменением только using один объект (надеюсь, хороший маленький using предмет) будет задерживаться, а Стоимость datatable доработки сведена к минимуму.

Наконец, объекты, требующие dispose доработки создать работу dataset для потока финализатора. Если idisposable ваш процесс завершения сложный, единственный datatable и неповторимый поток финализатора dispose-pattern будет тратить много времени idisposable на выполнение этих шагов, что resource-disposal может вызвать отставание resource-disposal в работе и поэтому заставляют resource-disposal задерживаться больше предметов ждем datasets доработки. Следовательно, жизненно disposal важно, чтобы финализаторы disposal работают так же мало, как возможный. Помните idisposable также, что хотя все указатели using объектов остаются действительными во idisposable время доработки это может dispose-pattern быть случай, когда эти using указатели ведут к объекты, которые disposal уже были доработан и поэтому disposal может быть меньше чем полезно. Как disposal правило, безопаснее всего Избегайте dataset следующих указателей на объекты dataset в код завершения, даже disposing если указатели действительны. Безопасный, короткий путь dispose-pattern кода завершения является datasets наилучшим.

Возьмите это у disposing кого-то, кто видел сотни dispose мегабайт таблиц данных без datatable ссылок в Gen2: это чрезвычайно disposing важно и полностью упускается datatable из ответов в этой теме.

Ссылки:

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/

datatable

dataset

dispose

idisposable

using

2022-10-09T05:18:16+00:00