Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
C#_Console.doc
Скачиваний:
0
Добавлен:
01.05.2025
Размер:
1.4 Mб
Скачать

Шаблон реализации iDisposable.

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

  • При вызове любых операций они обязаны отслеживать, находиться ли объект в рабочем состоянии или уже был деинициализирован при помощи метода Dispose.

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

//Объект, поддерживающий модель детерминированного уничтожения

public class BaseResource: IDisposable

{

// Некоторый объект операционной системы,

//требующий своего закрытия после уничтожения.

private IntPtr handle;

// Управляемые ресурсы среды .NET

private Component Components;

// Специальный внутренний флаг, определяющий была ли произведена //деинициализация объекта

private bool disposed = false;

// Конструктор данного класса

public BaseResource( )

{

//Здесь будет размещаться инициализирующий код объекта

}

// Опишем метод Dispose интерфейса IDisposable.

// Не делайте этот метод виртуальным,

//чтобы потомки не смогли перекрыть его

public void Dispose( )

{

Dispose(true);

// Предотвращает автоматический вызов Finalize

// при сборке мусора, чтобы метод Dispose не был вызван повторно.

GC.SuppressFinalize(this);

}

//Данный метод специально объявлен виртуальным, т.к. он собственно

// и занимается реальным освобождением ресурсов.

protected virtual void Dispose(bool disposing)

{

// Проверим, вызвался ли метод ранее.

//Это всего лишь предеосторожность, чтобы не получить ошибку

//при повторном вызове метода Dispose.

//Т.е. проверим, в каком состоянии находится наш объект в текущий //момент.

if(!this.disposed)

{ // Если параметр, переданный методу=true,

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

//помощи GC.SuppressFinalize(this);

if(disposing)

{

//Освобождаем управляемые ресурсы.

Components.Dispose( );

}

// Устанавливаем флаг, говорящий о том, что ресурсы уже //освобождены и объект более не доступен

this.disposed = true;

// Теперь освобождаем неуправляеиые ресурсы (уровня //операционной системы), к примеру вызовем Release.

Release(handle);

handle = IntPtr.Zero;

}

}

// Объявим финализатор, который будет вызван только в том случае, если до //этого не был вызван метод Dispose

~BaseResource( )

{

//В самом деструкторе не стоит очищать ресурсы, вместо этого лучше //центализованно поместить весь код очистки в метод Dispose. //Вызываем Dispose с параметром false, который говорит о отм, что //нужно очистить только неуправляемые ресурсы.

Dispose(false);

}

// Некоторый метод, который производит некоторую операцию, предоставляемую //классом.

public void DoSomething( )

{

//Проверяем, не был ли удален наш объект

if(this.disposed)

{

//Если объекта больше не существует, выбрасываем //соответствующее исключение

throw new ObjectDisposedException(...);

}

// Здесь выполняется соответствующая операция.

}

}

93

Центр авторизованного обучения IT-технологиям

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]