Номер статьи: KB000004
Связанные блоки:
Оператор Dispose в языке Fore предназначен для решения довольно узкого класса проблем, связанных с недетерминированным временем освобождения объектов. Уничтожение созданных и уже неиспользующихся объектов (на которые нет ссылок) производится сборщиком мусора (garbage collector). Как правило, запуск сборщика мусора производится в моменты простоя системы. Получается, что между удалением ссылок на объект и его фактическим уничтожением может пройти довольно большой период времени. Наличие этого периода, а также его недетерминированность, могут вызывать проблемы при разработке. Рассмотрим это на следующем примере:
Sub UserProc;
Var
FileName: String;
Fs: FileStream;
Begin
FileName := Path.GetTempFileName;
Fs := New FileStream.Create(FileName, FileOpenMode.Create, FileShare.Exclusive);
Try
// Действия
с файлом
Finally
Fs := Null;
File.Delete(FileName);
End Try;
End Sub UserProc;
В данном примере создается временный файл, затем с ним производятся некоторые действия и файл удаляется. При запуске примера на строке File.Delete возникнет стандартная исключительная ситуация: «Процесс не может получить доступ к файлу, т.к. файл занят другим процессом». Некоторые разработчики считают, что после присвоения переменной Fs значения Null единственная ссылка на объект «файловый поток» прекратит существование и файл будет закрыт. Фактически этого не происходит, так как объект «файловый поток» остается в памяти до следующей «сборки мусора», несмотря на отсутствие ссылок. Как следствие, файл не освобождается и не может быть удален.
Таким образом, требуется механизм детерминированного освобождения ссылок на ресурсы. Для этого и предназначен оператор Dispose. Если по каким-либо причинам необходимо детерминированным образом освободить ссылку на объект и уничтожить его, то используйте данный оператор с указанием переменной.
При использовании оператора есть ряд ограничений:
Оператор эффективно применять только к объектам системных классов, которые являются «обертками» над COM-объектами. Для объектов пользовательских классов, описанных прикладными разработчиками, применять его бессмысленно.
После выполнения оператора Dispose не происходит очистка ссылки на объект-обертку; переменной, содержащей ссылку, значение Null не присваивается. Производится освобождение ссылки на системный COM-объект, что позволяет его уничтожить и освободить занятые ресурсы. После вызова оператора Dispose любые обращения к объекту будут вызывать исключительную ситуацию.
Если на данный объект есть другие ссылки, то вызов оператора Dispose ожидаемого эффекта не даст. Для освобождения внутреннего COM-объекта необходимо ликвидировать все ссылки на него.
Корректное освобождение неиспользуемых объектов:
Sub UserProc;
Var
FileName: String;
Fs: FileStream;
Begin
FileName := Path.GetTempFileName;
Fs := New FileStream.Create(FileName, FileOpenMode.Create, FileShare.Exclusive);
Try
// Действия
с файлом
Finally
Dispose Fs;
File.Delete(FileName);
End Try;
End Sub UserProc;
См. также: