Когда вы не можете использовать SafeHandle поверх Finalizer / IDisposable? - PullRequest
4 голосов
/ 13 ноября 2011

Когда вы видите всю проблему финализатора / IDisposable, обычно видно, что в конце, после всего длинного описания, будет что-то в значении «LOL, то, что я сказал, было на самом деле бесполезным, вы должны использоватьSafeHandle вместо этого пока! "Поэтому мне интересно, в каком случае SafeHandle не подходит, так что вам придется прибегнуть к финализатору / IDisposable по-старому?

Ответы [ 3 ]

3 голосов
/ 13 ноября 2011

Очевидно, что когда неуправляемый ресурс, который вы переносите, не получен через дескриптор. Что редко, но не случайно. Примером может служить написание оболочки в коде C ++ / CLI, обычно выполняемой для переноса нативного класса C ++. Ресурс - это память. Неуправляемый вид.

Тем не менее, вы можете потратить карьеру на написание управляемого кода, а никогда написать финализатор. Финализаторы входят в рамки классов.

3 голосов
/ 13 ноября 2011

Когда вы не можете использовать SafeHandle поверх Finalizer / IDisposable?

Очевидный ответ почти никогда, Safehandles предлагают много преимуществ.

Но код внутри ReleasHandle() должен соответствовать ограничениям Области ограниченного выполнения (CER) . Он не может (не должен) вызывать код, который может генерировать или блокировать. Поэтому, если ваша очистка более сложная и «ненадежная», вам все равно придется использовать Финализатор / деструктор.

Но для дескрипторов (ОС) вы можете и всегда должны использовать SafeHandle.

0 голосов
/ 14 ноября 2011

Многие типы неуправляемых ресурсов могут выполнять свои обязанности по очистке, используя простой вызов API для дескриптора.Такие ресурсы могут (и часто должны) быть инкапсулированы в SafeHandle.Некоторые другие типы неуправляемых ресурсов (например, подписки на события, поддерживаемые долгоживущими издателями) несут обязанности по очистке, которые не могут быть хорошо обработаны с помощью финализатора.Финализаторы могут быть бесполезны, если семантически бесполезные сильные ссылки поддерживают оставленные объекты живыми, и могут быть непригодны для использования с ресурсами, которые должны быть очищены потоком, который их создает.Нет необходимости писать собственный финализатор для таких ресурсов, потому что ни один тип финализатора не устранит абсолютную 100% необходимость обеспечения их детерминированной утилизации.

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

...