System.Runtime.InteropServices. класс Сейф Handle

В этой статье приводятся дополнительные замечания к справочной документации по этому API.

Класс SafeHandle обеспечивает критическое завершение обработки ресурсов, предотвращая преждевременное удаление дескрипторов сборкой мусора и перезапуска операционной системой для ссылки на непреднамеренные неуправляемые объекты.

Почему Сейф Handle?

Хотя переопределяет Object.Finalize метод, разрешающий очистку неуправляемых ресурсов при сборе мусора, в некоторых случаях методоизменяемые объекты могут быть удалены сборкой мусора при выполнении метода в вызове платформы. Если средство завершения освобождает дескриптор, переданный вызову этой платформы, он может привести к повреждению. Дескриптор также может быть восстановлен, пока метод заблокирован во время вызова платформы, например при чтении файла.

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

Что делает Сейф Handle

Класс SafeHandle упрощает несколько из этих проблем со временем существования объекта и интегрируется с вызовом платформы, чтобы ресурсы операционной системы не утечки. Класс SafeHandle устраняет проблемы со временем существования объекта путем назначения и освобождения дескрипторов без прерывания. Он содержит критически важный метод завершения, который гарантирует, что дескриптор закрыт и гарантированно выполняется во время непредвиденных AppDomain выгрузок, даже в случаях, когда вызов платформы, как предполагается, находится в поврежденном состоянии.

Так как SafeHandle наследуется от CriticalFinalizerObject, все некритические методы завершения вызываются до любого из критических методов завершения. Методы завершения вызываются к объектам, которые больше не живут во время того же прохода сборки мусора. Например, FileStream объект может запустить обычный метод завершения для очистки существующих буферных данных без риска утечки или перезапуска дескриптора. Это очень слабое упорядочение между критическими и некритичными методами завершения не предназначено для общего использования. Она существует в первую очередь для поддержки миграции существующих библиотек, позволяя этим библиотекам использовать SafeHandle без изменения их семантики. Кроме того, критически важный метод завершения и все вызовы, такие как SafeHandle.ReleaseHandle() метод, должны находиться в ограниченном регионе выполнения. Это накладывает ограничения на код, который можно записать в графе вызовов метода завершения.

Операции вызова платформы автоматически увеличивают число ссылок дескрипторов, инкапсулированных SafeHandle ими после завершения. Это гарантирует, что дескриптор не будет переработан или закрыт неожиданно.

При создании SafeHandle объектов можно указать владение базовым дескриптором, указав значение ownsHandle аргументу в конструкторе SafeHandle классов. Это определяет, будет ли SafeHandle объект выпускать дескриптор после удаления объекта. Это полезно для дескрипторов с особыми требованиями к жизни или для использования дескриптора, время существования которого контролируется кем-то другим.

Классы, производные от Сейф Handle

SafeHandle — это абстрактный класс оболочки для дескрипторов операционной системы. Наследовать от этого класса сложно. Вместо этого используйте производные классы в пространстве имен Microsoft.Win32.SafeHandles, которые предоставляют безопасные дескрипторы для следующих элементов: