Примечание
Для доступа к этой странице требуется авторизация. Вы можете попробовать войти или изменить каталоги.
Для доступа к этой странице требуется авторизация. Вы можете попробовать изменить каталоги.
В этой статье приводятся дополнительные замечания к справочной документации по этому API.
Класс SafeHandle обеспечивает критическую финализацию ресурсов дескрипторов, предотвращая преждевременное удаление дескрипторов сборкой мусора и переработки операционной системой для ссылки на нежелательные неуправляемые объекты.
Почему SafeHandle?
Хотя переопределение метода Object.Finalize, позволяющее очистить неуправляемые ресурсы при сборке мусора, в некоторых случаях финализируемые объекты могут быть удалены сборщиком мусора при выполнении метода в платформенном вызове. Если финализатор освобождает дескриптор, переданный платформенному вызову, это может привести к его повреждению. Дескриптор также может быть восстановлен, когда выполнение метода заблокировано во время вызова платформы, например, при чтении файла.
Что более критично, так как Windows агрессивно перерабатывает дескрипторы, дескриптор может быть переработан и указывать на другой ресурс, который может содержать конфиденциальные данные. Это называется повторной атакой и может потенциально повредить данные, а также быть угрозой безопасности.
Что делает SafeHandle
Класс SafeHandle упрощает несколько проблем, связанных с временем жизни объектов, и интегрируется с вызовами кода платформы, чтобы избежать утечек ресурсов операционной системы. Класс SafeHandle устраняет проблемы со временем существования объекта путем назначения и освобождения дескрипторов без прерывания. Он содержит критически важный метод завершения, который гарантирует, что дескриптор закрыт и гарантированно выполняется во время непредвиденных AppDomain выгрузок, даже в случаях, когда вызов платформы, как предполагается, находится в поврежденном состоянии.
Так как SafeHandle наследуется от CriticalFinalizerObject, все некритические методы завершения вызываются до любого из критических методов завершения. Методы завершения вызываются для объектов, которые больше не используются во время того же захода сборки мусора. Например, FileStream объект может запустить обычный метод завершения для очистки существующих буферных данных без риска утечки или перезапуска дескриптора. Эта очень слабая упорядоченность между критическими и некритичными финализаторами не предназначена для общего использования. Она существует в первую очередь для поддержки миграции существующих библиотек, позволяя этим библиотекам использовать SafeHandle без изменения их семантики. Кроме того, критически важный финализатор и все вызываемые им методы, такие как метод SafeHandle.ReleaseHandle(), должны находиться в ограниченной области выполнения. Это накладывает ограничения на код, который можно записать в граф вызовов финализатора.
Операции вызова платформы автоматически увеличивают число ссылок дескрипторов, инкапсулированных в SafeHandle, и уменьшают их после завершения. Это гарантирует, что дескриптор не будет переиспользован или закрыт неожиданно.
При создании SafeHandle объектов, владение базовым дескриптором можно определить, указав ownsHandle
в качестве аргумента в конструкторе класса SafeHandle. Определяет, будет ли объект SafeHandle освобождать дескриптор после удаления. Это полезно для дескрипторов с особыми требованиями к сроку службы или для использования дескриптора, срок службы которого контролируется кем-то другим.
Классы, производные от SafeHandle
SafeHandle — это абстрактный класс оболочки для дескрипторов операционной системы. Наследовать от этого класса трудно. Вместо этого используйте производные классы в Microsoft.Win32.SafeHandles пространстве имен, которые обеспечивают защищенные дескрипторы для следующих:
- Файлы ( SafeFileHandle класс).
- Сопоставленные с памятью файлы (класс SafeMemoryMappedFileHandle).
- Трубы (SafePipeHandle класс).
- Представления памяти (класс SafeMemoryMappedViewHandle).
- Конструкции криптографии (SafeNCryptHandle,SafeNCryptKeyHandleSafeNCryptProviderHandle, и SafeNCryptSecretHandle классы).
- Процессы ( SafeProcessHandle класс).
- Разделы реестра (класс SafeRegistryHandle).
- Дескрипторы ожидания (класс SafeWaitHandle).