Каково различие между использованием IDisposable по сравнению с деструктором в C#?

Не поймите, почему люди делают это настолько сложным:

objs.sort(function(a, b){
  return a.last_nom > b.last_nom;
});

Для более строгих движков:

objs.sort(function(a, b){
  return a.last_nom == b.last_nom ? 0 : +(a.last_nom > b.last_nom) || -1;
});

Смените оператор, чтобы он отсортировался по обратному алфавитному порядку.

95
задан Jordan Parmer 4 December 2008 в 12:14
поделиться

7 ответов

Финализатор (иначе деструктор) является частью сборки "мусора" (GC) - это неопределенно, когда (или даже если) это происходит, как GC главным образом происходит в результате давления памяти (т.е. нуждаются в большем количестве пространства). Финализаторы обычно только используются для чистки неуправляемый ресурсы, так как управляемые ресурсы будут иметь свой собственный набор/распоряжение.

Следовательно IDisposable привык к [1 110] детерминировано , очищают объекты, т.е. теперь. Это не собирает память объекта (который все еще принадлежит GC) - но используется, например, для закрытия файлов, соединений с базой данных, и т.д.

существует много предыдущих тем на этом:

Наконец, обратите внимание, что это весьма характерно для IDisposable объект также иметь финализатор; в этом случае, Dispose() обычно вызовы GC.SuppressFinalize(this), означая, что GC не выполняет финализатор - это просто выбрасывает (намного более дешевую) память. Финализатор все еще работает, если Вы забываете к Dispose() объект.

120
ответ дан Community 5 November 2019 в 13:00
поделиться

Роль Finalize() метод должен гарантировать, что объект.NET может очистить неуправляемые ресурсы , когда собрано "мусор" . Однако объекты, такие как соединения с базой данных или обработчики файлов должны быть выпущены как можно скорее, вместо этого при доверии сборке "мусора". Для этого необходимо реализовать IDisposable интерфейс и высвободить средства в Dispose() метод.

23
ответ дан Igal Tabachnik 5 November 2019 в 13:00
поделиться

Существует очень хорошее описание на MSDN:

основное использование этого интерфейса к , высвобождают неуправляемые средства . Сборщик "мусора" автоматически освобождает память выделенный управляемому объекту, когда тот объект больше не используется. Однако не возможно предсказать, когда сборка "мусора" произойдет . Кроме того, сборщик "мусора" не знает о неуправляемых ресурсах , таких как дескрипторы окна, или открытые файлы и потоки.

Использование Расположить метод этого интерфейса к [1 110] явно неуправляемые ресурсы выпуска в сочетании со сборщиком "мусора". потребитель объекта может назвать этот метод, когда объект больше не необходим.

9
ответ дан abatishchev 5 November 2019 в 13:00
поделиться

Единственной вещью, которая должна быть в деструкторе C#, является эта строка:

Dispose(False);

Вот именно. Ничто иное никогда не должно быть в том методе.

8
ответ дан Jonathan Allen 5 November 2019 в 13:00
поделиться

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

деструктор А никогда не должен обычно использоваться. Это только выполняется, .net хочет, чтобы он работал. Это будет только бежать за мусором collectoin цикл. Это никогда не может на самом деле выполняться в течение жизненного цикла Вашего приложения. Поэтому Вы никогда не должны помещать код в деструктор, который 'должен' быть выполнен. Вы также не можете полагаться ни на какие существующие объекты в классе для существования, когда он работает (они, возможно, были уже очищены как порядок, в которых деструкторах, выполненных в, не гарантирован).

IDisposible должен использоваться каждый раз, когда у Вас есть объект, который создает ресурсы, которым нужна чистка (т.е., файл и графические дескрипторы). На самом деле многие утверждают, что что-либо, Вы вставляете деструктор, должно быть putin IDisposable из-за упомянутых выше причин.

Большинство классов будет звонить, располагают, когда финализатор выполняется, но это просто там как безопасность и никогда не должно полагаться. Необходимо явно расположить что-либо, что реализует IDisposable, когда Вы сделаны с ним. При реализации IDisposable необходимо звонить, располагают в финализаторе. См. http://msdn.microsoft.com/en-us/library/system.idisposable.aspx для примера.

2
ответ дан DaEagle 5 November 2019 в 13:00
поделиться

Вот еще одна прекрасная статья, которая проясняет туман вокруг IDisposable, GC и утилизации.

Chris Lyons WebLog Demystifying Dispose

0
ответ дан 24 November 2019 в 05:51
поделиться

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

Лично я считаю, что позиция Джеффри Рихтера о том, что вызов Dispose не является обязательным, невероятно слабая. В обоснование своего мнения он приводит два примера.

В первом примере он говорит, что вызов Dispose в элементах управления Windows Forms утомителен и не нужен в основных сценариях. Однако он не упоминает, что Dispose на самом деле вызывается автоматически контейнерами управления в этих основных сценариях.

Во втором примере он заявляет, что разработчик может ошибочно предположить, что экземпляр из IAsyncResult. WaitHandle следует агрессивно удалять, не осознавая, что свойство лениво инициализирует дескриптор ожидания, что приводит к ненужному снижению производительности. Но проблема с этим примером заключается в том, что сам IAsyncResult не соответствует собственным опубликованным рекомендациям Microsoft по работе с объектами IDisposable . То есть, если класс содержит ссылку на тип IDisposable , тогда сам класс должен реализовывать IDisposable . Если IAsyncResult следовал этому правилу, то его собственный метод Dispose мог бы принять решение относительно того, какие из его составляющих элементов необходимо удалить.

Так что, если у кого-то нет более веских аргументов, я собираюсь привести оставайтесь в "всегда вызывайте Dispose"

4
ответ дан 24 November 2019 в 05:51
поделиться
Другие вопросы по тегам:

Похожие вопросы: