IDisposable GC.SuppressFinalize(это) местоположение
Я использую шаблон реализации по умолчанию (шаблон) для моего кода.
фрагмент кода:
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;
}
}
5 ответов
Я предполагаю, что это явный случай шаблона дизайна шаблона.
Ваш абстрактный класс предназначен для выполнения всех важных / необходимых задач (здесь GC.SuppressFinalize(this)) и позволяет производному классу переопределять только некоторую часть кода.
Здесь есть 2 случая:
Фрагмент 1, SuppressFinalize, в Dispose
Фрагмент 2, SuppressFinalize, в Dispose(true)
Здесь, фрагмент 1, гарантирует, что GC.SuppressFinalize всегда выполняется. В то время как фрагмент 2, оставляет выполнение GC.SuppressFinalize во власти производного класса.
Таким образом, поместив GC.SuppressFinalize в метод Dispose, вы, как разработчик вашего класса, всегда будете уверены, что независимо от того, какой код написан производными классами, GC.SuppressFinalize будет выполняться.
Это только преимущество написания SuppressFinalize в Dispose, а не Dispose(true).
Dispose(bool isDisposing)
метод не является частью IDisposable
интерфейс.
Вы бы обычно звонили Dispose(true)
от твоего Dispose
метод и вызов Dispose(false)
от вашего финализатора, как запасной вариант в случае, когда объект еще не был утилизирован.
призвание SuppressFinalize
говорит GC, что нет необходимости вызывать финализатор вашего объекта, вероятно, потому что вся ваша очистка была сделана, когда Dispose
назывался.
Если в вашем классе нет финализатора, вам не нужно звонить SuppressFinalize
вообще, так как нет финализатора для подавления!
У Джо Даффи есть отличные рекомендации по утилизации, доработке, уборке мусора и т. Д.
Причина. Уничтожение происходит, когда управляемый код (ваш код) избавляется от объекта, тем самым отказываясь от завершения. Люди обычно создают другой маршрут в Dispose(удаление bool) через финализатор, и вызов не будет иметь никакого смысла для финализатора.
Я думаю, что любой макет можно было бы выбрать, но, вероятно, они хотели подчеркнуть "поместить весь код освобождения в этот метод" в защищенный метод Dispose, поэтому они помещают другой артефакт удаления (подавление финализации) в другое место.
Кроме того, предположим, что у производного класса была другая причина для вызова защищенного метода Dispose, но он все же хотел, чтобы завершился процесс (по какой-либо воображаемой причине, я не знаю).
Идея состоит в том, что ваш код очистки должен вызываться только один раз. Однако есть две точки входа: 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.