Я использую шаблон (шаблон) для IDisposable по умолчанию для моего кода.
сниппет:
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
protected virtual void Dispose(bool isDisposing)
{
if (!this.disposed)
{
if (isDisposing)
{
//cleanup managed resources
}
//cleanup unmanaged resources
this.disposed = true;
}
}
Мой вопрос: почему вызов "GC.SuppressFinalize(this)" в публичном методе Dispose? Я бы поставил "GC.SuppressFinalize(this)" в разделе "if (isDisposing)" защищенного метода после удаления управляемых ресурсов.
Вот так:
protected virtual void Dispose(bool isDisposing)
{
if (!this.disposed)
{
if (isDisposing)
{
//cleanup managed resources
GC.SuppressFinalize(this);
}
//cleanup unmanaged resources
this.disposed = true;
}
}
Ответ 1
Я полагаю, что это явный случай шаблона шаблона дизайна.
Ваш абстрактный класс предназначен для выполнения всех важных/необходимых задач (здесь GC.SuppressFinalize(this)) и позволяет производному классу переопределить только часть кода.
Здесь два случая:
Фрагмент 1, SuppressFinalize, в утилите
Snippet 2, SuppressFinalize, в Dispose (true)
Здесь, Snippet 1, убедитесь, что GC.SuppressFinalize всегда выполняется. В то время как фрагмент 2 оставляет выполнение GC.SuppressFinalize по милости производного класса.
Итак, поставив GC.SuppressFinalize, в методе Dispose вы как разработчик своего класса всегда будете уверены, что независимо от того, какой код написан производными классами, GC.SuppressFinalize будет выполнен.
Это только преимущество написания SuppressFinalize в Dispose, а не Dispose (true).
Ответ 2
Метод Dispose(bool isDisposing)
не является частью интерфейса IDisposable
.
Обычно вы вызываете Dispose(true)
из своего метода Dispose
и вызываете Dispose(false)
из вашего финализатора, как резерв в если объект еще не был удален.
Вызов SuppressFinalize
сообщает GC, что нет необходимости вызывать финализатор вашего объекта, предположительно потому, что вся ваша очистка выполнялась, когда Dispose
был вызван.
Если у вас нет финализатора на вашем классе, вам не нужно вообще называть SuppressFinalize
, так как нет финализатора для подавления!
Joe Duffy имеет несколько отличных рекомендаций по утилизации, финализации, сборке мусора и т.д..
Ответ 3
Я думаю, что любой макет мог быть выбран, но, вероятно, они хотели подчеркнуть "положить весь код освобождения в этом методе" в защищенный метод Dispose, поэтому они помещают другой артефакт распоряжения (подавление финализации) в другом месте.
Кроме того, предположим, что производный класс имел еще одну причину вызова защищенного метода Dispose, но все еще нуждался в завершении (по любой мыслимой причине, я не знаю).
Ответ 4
Причина. Задача - когда управляемый код (ваш код) удаляет объект, тем самым отказываясь от завершения. Люди обычно создают другой маршрут в Dispose (bool disposing) через финализатор, и вызов не будет иметь никакого смысла для финалиста.
Ответ 5
Идея заключается в том, что ваш код очистки должен вызываться только один раз. Однако есть две точки входа: метод Dispose
и финализаторы объектов. Когда вызывается Dispose
, вы отказываетесь от завершения, чтобы ваш код очистки вызывался только один раз. Код здесь может показать его лучше.
Цитата:
// NOTE: Leave out the finalizer altogether if this class doesn't
// own unmanaged resources itself, but leave the other methods
// exactly as they are.