Какой-либо смысл установить obj = аннулирует (Ничто) в Не Располагает ()?

Есть ли любой смысл установить пользовательский объект на null(Nothing в VB.NET) в Dispose() метод? Это могло предотвратить утечки памяти, или это бесполезно?!

Давайте рассмотрим два примера:

public class Foo : IDisposable
{
    private Bar bar; // standard custom .NET object

    public Foo(Bar bar) {
        this.bar = bar;
    }
    public void Dispose() {
        bar = null; // any sense?
    }
}

public class Foo : RichTextBox
{
    // this could be also: GDI+, TCP socket, SQl Connection, other "heavy" object
    private Bitmap backImage; 

    public Foo(Bitmap backImage) {
        this.backImage = backImage;
    }

    protected override void Dispose(bool disposing) {
        if (disposing) {
            backImage = null;  // any sense?
        }
    }
}
32
задан serhio 18 February 2010 в 13:55
поделиться

7 ответов

Цель Dispose () - разрешить очистку ресурсов, которые не обрабатываются сборщиком мусора. Об объектах заботится сборщик мусора, поэтому в обычных обстоятельствах нет необходимости устанавливать ссылку на null.

Исключение составляют случаи, когда вы ожидаете, что вызывающий абонент вызовет Dispose и удерживает экземпляр после этого. В этом случае может быть хорошей идеей установить для внутренней ссылки значение null. Однако одноразовые экземпляры обычно утилизируются и выпускаются одновременно. В этих случаях это не будет иметь большого значения.

20
ответ дан 27 November 2019 в 20:47
поделиться

Это может иметь смысл, если вы хотите каким-то образом предотвратить повторное использование удаленного принадлежащего экземпляра.

Когда вы устанавливаете ссылки на одноразовые поля равными нулю, вы гарантированно больше не будете использовать экземпляры.

Вы не получите ObjectDisposedException или любое другое недопустимое состояние, вызванное использованием принадлежащего удаленного экземпляра (вы можете получить NullReferenceException , если не проверяете наличие нулей).

Это может не иметь для вас смысла, если все IDisposable объекты имеют свойство IsDisposed и / или генерируют ObjectDisposedException , если они используются после того, как они были disposed - некоторые могут нарушить этот принцип, и установка их на null может предотвратить возникновение нежелательных эффектов.

1
ответ дан 27 November 2019 в 20:47
поделиться

Лично я склонен; по двум причинам:

  • это означает, что если кто-то забыл освободить Foo (возможно, из события), любые нижестоящие объекты (в данном случае Bitmap ) все еще могут быть собраны (в какой-то момент в будущем - когда GC захочет); вполне вероятно , что это всего лишь поверхностная оболочка неуправляемого ресурса, но каждая мелочь помогает.
    • Я правда не например, случайно оставив весь граф объекта висеть на месте только потому, что пользователь забыл отцепить одно событие; IDisposable - удобный переключатель «почти убивает» - почему бы не отсоединить все доступное?
  • что более важно, теперь я могу дерзко использовать это поле для проверки (в методах и т. Д.) На предмет удаления, бросая ObjectDisposedException , если это null
24
ответ дан 27 November 2019 в 20:47
поделиться

Это просто бесполезно. Я считаю, что установка значения NULL в старые времена COM / VB уменьшила бы количество ссылок.

Это не относится к .NET. Когда вы устанавливаете bar на null, вы ничего не разрушаете и не освобождаете. Вы просто меняете ссылку, на которую указывает полоса, с вашего объекта на «null».Ваш объект все еще существует (хотя теперь, поскольку на него ничего не ссылается, он в конечном итоге будет собран мусором). За некоторыми исключениями и в большинстве случаев это то же самое, что произошло бы, если бы вы просто изначально не сделали Foo IDisposable.

Основная цель IDisposable - позволить вам освободить неуправляемых ресурсов, таких как сокеты TCP, соединения SQL или что-то еще. Обычно это делается путем вызова любой функции очистки, предоставляемой неуправляемым ресурсом, а не путем установки ссылки на «null».

4
ответ дан 27 November 2019 в 20:47
поделиться

Цель dispose () - очистить неуправляемые ресурсы. Соединения TCP, соединения с базой данных и другие объекты базы данных, а также множество таких неуправляемых ресурсов должны быть освобождены разработчиком в методе удаления. Так что это действительно имеет смысл.

0
ответ дан 27 November 2019 в 20:47
поделиться

Если вы посмотрите на узоры проектирования, почти все они могут быть избыточными. Но то, что образец означает широко используемый подход к решению подобного типа проблем. Образец конструкции обеспечивает подход или решение на уровне конструкции для набора аналогичных типов задач конструкции. Использование образца конструкции помогает решить проблему и, следовательно, быстрее ее решить.

-121--688816-

Для запроса XML-файла можно использовать E4X или XPath . Я бы рекомендовал использовать новую технологию E4X, так как она более проста в использовании, чем XPath.

jQuery предлагает только стандартные иерархические функции для анализа XML-файлов ( см. здесь ), так как это не его цель делать иначе.

-121--3959356-

В C # установка для объекта значения null означает освобождение ссылки на объект.

Таким образом, теоретически лучше деблокировать ссылку на управляемые объекты в методе Dispose-Method в C #, но только для возможности GC собрать объект, на который имеется ссылка, до сбора удаляемого объекта. Поскольку оба объекта, скорее всего, будут собраны в одном и том же прогоне, GC будет наиболее успешно распознавать, что на объект, на который имеется ссылка, ссылается только удаляемый тип, так что оба объекта могут быть собраны.

Также необходимость выпуска ссылки очень мала, так как все публичные члены вашего одноразового класса должны бросить исключение, если класс уже ликвидирован. Таким образом, после удаления метода, на который ссылается ссылка, доступ к объекту не будет успешным.

1
ответ дан 27 November 2019 в 20:47
поделиться

В VB.NET есть смысл установить в Nothing объявленные Private WithEvents объекты.

Обработчики, использующие ключевое слово Handles, будут удалены таким образом из этих объектов.

1
ответ дан 27 November 2019 в 20:47
поделиться