Looking for .net Keywords? Try Ask4Keywords

.NET Framework Надлежащее удаление и завершение объектов


пример

Поскольку Dispose () и финализаторы нацелены на разные цели, класс, управляющий ресурсами с большой памятью, должен реализовать оба из них. Следствием является запись класса, чтобы он хорошо справлялся с двумя возможными сценариями:

  • Когда вызывается только финализатор
  • Когда Dispose () вызывается сначала и позже, вызывается также финализатор

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

  • Закрытие уже закрытого соединения с базой данных, вероятно, не будет иметь никакого эффекта, поэтому оно будет работать
  • Обновление некоторого «количества использования» опасно и приведет к неправильному результату при вызове дважды, а не в один раз.

Более безопасное решение обеспечивает по дизайну, что код очистки вызывается один раз и только один раз, независимо от внешнего контекста. Это может быть достигнуто «классическим способом» с использованием выделенного флага:

public class DisposableFinalizable1: IDisposable
{
    private bool disposed = false;

    ~DisposableFinalizable1() { Cleanup(); }

    public void Dispose() { Cleanup(); }

    private void Cleanup()
    {
        if(!disposed)
        {
            // Actual code to release resources gets here, then
            disposed = true;
        }
    }
}

В качестве альтернативы сборщик мусора предоставляет специальный метод SuppressFinalize (), который позволяет пропустить финализатор после вызова Dispose:

public class DisposableFinalizable2 : IDisposable
{
    ~DisposableFinalizable2() { Cleanup(); }

    public void Dispose()
    {
        Cleanup();
        GC.SuppressFinalize(this);
    }

    private void Cleanup()
    {
        // Actual code to release resources gets here
    }
}