581
Освобождение.ресурсов.при.помощи.механизма.финализации
Обратите внимание, что класс
SafeHandleZeroOrMinusOneIsInvalid
явля-
ется абстрактным, поэтому надо создать дочерний класс, который переопреде-
лит защищенный конструктор и абстрактный метод
ReleaseHandle
. На плат-
форме Microsoft .NET Framework есть несколько открытых классов, производ-
ных от
SafeHandleZeroOrMunusOneIsInvalid
, в числе которых
SafeFileHandle
,
SafeRegistryHandle
,
SafeWaitHandle
и
SafeMemoryMappedViewHandle
. А
так
выглядит класс
SafeFileHandle
:
public sealed class
SafeFileHandle : SafeHandleZeroOrMinusOneIsInvalid {
public SafeFileHandle(IntPtr preexistingHandle, Boolean ownsHandle)
: base(ownsHandle) {
base.SetHandle(preexistingHandle);
}
protected override Boolean ReleaseHandle() {
// Сообщить Windows, что системный ресурс нужно закрыть
return Win32Native.CloseHandle(base.handle);
}
}
Класс
SafeWaitHandle
реализован сходным образом. Единственной причиной
для создания разных классов с похожими реализациями является обеспечение
безопасности типов: компилятор не позволит использовать файловый дескриптор
в качестве аргумента метода, принимающего дескриптор блокировки, и наоборот.
Метод
ReleaseHandle
класса
SafeRegistryHandle
вызывает Win32-функцию
RegCloseKey
.
Жаль, что на платформе .NET Framework отсутствуют дополнительные клас-
сы, служащие оболочкой
различных системных ресурсов, например таких, как
SafeProcessHandle
,
SafeThreadHandle
,
SafeTokenHandle
,
SafeLibraryHandle
(его
метод
ReleaseHandle
вызывал бы Win32-функцию
FreeLibrary
),
SafeLocalAl-
locHandle
(его метод
ReleaseHandle
вызывал бы Win32-функцию
LocalFree
)
и т. п.
Все эти классы (а также некоторые другие) есть в библиотеке FCL. Однако они
не предоставляются для открытого использования, являясь внутренними классами
сборок, в которых они определяются. Microsoft не афиширует эти классы, чтобы не
выполнять их полное тестирование и не тратить время на их документирование.
Если же вам
придется с ними столкнуться, рекомендую воспользоваться утилитой
ILDasm exe
или другим IL-декомпилятором, чтобы извлечь код этих классов и инте-
грировать его в исходный текст программы. Все эти классы тривиально реализуются
и их несложно написать самостоятельно.
Классы, производные от
SafeHandle
, чрезвычайно полезны — ведь они гаран-
тируют освобождение системного ресурса в ходе уборки мусора. Стоит добавить,
что у
типа
SafeHandle
есть еще две функциональные особенности. Во-первых,
когда производные от него типы используются в сценариях взаимодействия