области с ограничением выполнения
Области с ограничением управления являются частью механизма создания надежного управляемого кода. Область CER определяет область, в которой среда CLR не может создавать исключения, находящиеся за пределами диапазона, что будет препятствовать полному выполнению кода, находящегося в зоне. В этом регионе пользовательский код не может запустить код, который приведет к созданию исключений, находящихся за пределами диапазона. Метод PrepareConstrainedRegions должен следовать сразу перед блоком try и отмечать блоки catch, finally и fault как области с ограниченным управлением. После отметки в качестве области с ограничением код должен только вызывать другой код со строгими контрактами надежности, также код не должен выделять ресурсы или делать виртуальные вызовы неподготовленных или ненадежных методов, если только код не создан для обработки сбоев. Область CLR откладывает прерывание потока для кода, выполняемого в области CER.
Области с ограниченным выполнением используются в различных формах в CLR, кроме аннотируемого блока try, особенно важные методы завершения, выполняемые в классах, являются производными из класса CriticalFinalizerObject, и код выполняется с помощью метода ExecuteCodeWithGuaranteedCleanup.
Расширенная подготовка CER
Среда CLR заведомо подготавливает области с ограниченным выполнением во избежание нехватки памяти. Расширенная подготовка необходима, чтобы среда CLR не приводила к нехватке памяти во время JIT-компиляции или загрузки типа.
Разработчику необходимо указать, является ли область кода областью с ограниченным выполнением:
Область CER верхнего уровня, а также методы в графике полных вызовов, которые содержат примененный атрибут ReliabilityContractAttribute, были заранее подготовлены. Объект ReliabilityContractAttribute может только гарантировать Success или MayFail.
Расширенная подготовка не может быть выполнена для вызовов, которые не могут быть определены статически, например виртуальная диспетчеризация. В этих случаях используйте метод PrepareMethod. При использовании метода ExecuteCodeWithGuaranteedCleanup атрибут PrePrepareMethodAttribute должен быть применен для очистки кода.
Ограничения
Пользователи ограничены в типе кода, который они могут записывать в области CER. Код не может вызывать исключения, находящиеся за пределами диапазона, которые могут возникнуть вследствие следующих операций:
Явное выделение.
Упаковка–преобразование.
Получение блокировки.
Виртуальный вызов неподготовленных методов.
Вызов методов со слабым или несуществующим контрактом надежности.
В .NET Framework версии 2.0 эти ограничения являются правилами. Диагностика предоставлена посредством средств анализа кода.
Контракты надежности
ReliabilityContractAttribute является пользовательским атрибутом, с помощью которого документируются гарантии надежности и состояние повреждения текущего метода.
Гарантии надежности
Гарантии надежности, представленные значениями перечисления Cer, указывает степень надежности данного метода:
MayFail. При возникновении исключительных условий метод может завершиться неудачно. В этом случае метод сообщит об удачном или неудачном завершении вызвавшему его методу. Метод должен содержаться в области CER, чтобы он мог гарантированно передать возвращенное значение.
None. Метод, тип или сборка не имеют представления об области CER, поэтому, скорее всего, вызывать их из области CER не является безопасным. Преимущества гарантий CER не используются. Это подразумевает следующее:
При возникновении исключительных условий метод может завершиться неудачно.
Метод может сообщать о неудачном завершении или не делать этого.
Метод не создан для использования области CER (наиболее вероятный сценарий).
Если метод, тип или сборка не помечен явно как такой, который всегда выполняется успешно, он неявным образом отмечается как None.
Success. При возникновении исключительных условий, метод гарантированно завершится успешно. Чтобы достичь этого уровня чтения, всегда следует заключать вызываемый метод в область CER, даже если он вызывается из области, не являющейся CER. Выполнение метода считается успешным, если были завершены все поставленные задачи, несмотря на то, что успех можно оценивать субъективно. Например, если пометить свойство Count атрибутом ReliabilityContractAttribute(Cer.Success), это подразумевает, что, когда это свойство выполняется в области CER, оно всегда возвращает число элементов в ArrayList и никогда не оставляет внутренние поля неопределенными. Однако метод CompareExchange также отмечается как успешный с учетом, что успех может означать невозможность замены значения новым значением вследствие состояния гонки. Ключевым моментом является то, что поведение метода в таком случае документировано, а код CER не нуждается в дополнении для учета любого необычного поведения, чтобы не создавать правильный но ненадежный код.
Уровни повреждения
Уровни повреждения, представленные значениями перечисления Consistency, указывают на возможное количество повреждения состояния в определенной среде:
MayCorruptAppDomain. При возникновении исключительных условий среда CLR не обеспечивает согласованности состояний в текущем домене приложений.
MayCorruptInstance. При возникновении исключительных условий гарантируется, что метод ограничит повреждения состояний текущим экземпляром.
MayCorruptProcess, при возникновении исключительных условий среда CLR не обеспечивает согласованности состояний, то есть исключительное условие может повредить процесс.
WillNotCorruptState. При возникновении исключительных условий, гарантируется, что метод не повредит состояние.
Надежность try/catch/finally
Надежность try/catch/finally — это механизм обработки исключений с тем же уровнем предсказуемости, что и в неуправляемой версии. Блок catch/finally является областью CER. Методы в блоки нуждаются в предварительной подготовке и не должны прерываться.
В .NET Framework версии 2.0 код уведомляет во время выполнения о том, что попытка является надежной, посредством вызова метода PrepareConstrainedRegions сразу перед блоком try. Метод PrepareConstrainedRegions является членом класса поддержки компилятора RuntimeHelpers. Вызовите метод PrepareConstrainedRegions напрямую, ожидая его доступность посредством компиляторов.
Непрерываемые области
Непрерываемая область группирует набор инструкций в область CER.
В .NET Framework версии 2.0, обеспечивая доступность посредством поддержки компилятора, пользовательский код создает непрерываемые области с надежным механизмом try/catch/finally, которому предшествует вызов метода PrepareConstrainedRegions.
Критический объект метода завершения
CriticalFinalizerObject гарантирует запуск метода завершения сборщиком мусора. После выделения метод завершения и его график вызовов подготавливаются предварительно. Метод завершения выполняется в области CER и должен подчиняться всем ограничениям как области CER, так и методов завершения.
Любые типы, наследуемые из SafeHandle и CriticalHandle, гарантировано имеют собственный метод завершения, выполняемый в области CER. Реализуйте метод ReleaseHandle в производных классах SafeHandle, чтобы выполнить любой код, необходимый для освобождения дескриптора.
Код, не разрешенный в областях CER
Выполнение следующих операций запрещено в областях CER:
Явные выделения.
Получение блокировки.
Упаковка–преобразование.
Доступ к многомерным массивам.
Вызовы методов через отражение.
Проверки безопасности. Не выполняйте запросы, а только запросы компоновки.
Получение или задание полей в прозрачном прокси.
Сериализация.
Указатели функций и делегаты.