Поделиться через


Регионы ограниченного выполнения

Область ограниченного выполнения (CER) является частью механизма разработки надежного управляемого кода. CER определяет область, в которой среда CLR ограничивает выдачу исключений, возникающих вне основного потока, которые препятствуют выполнению кода в полном объеме. В этом регионе пользовательский код ограничен выполнением кода, что может привести к возникновению внеочередных исключений. Метод PrepareConstrainedRegions должен немедленно предшествовать блоку try и отмечает метки catch, finally, а также блоки fault как ограниченные области выполнения. После того как регион отмечен как ограниченный, код должен вызывать только код с жесткими контрактами надежности и не должен выделять ресурсы или выполнять виртуальные вызовы к неподготовленным или ненадежным методам, за исключением случаев, когда код готов обрабатывать сбои. Среда CLR задерживает прерывания потока для кода, выполняемого в CER.

Это важно

CER поддерживается только в .NET Framework. Эта статья не относится к .NET Core или .NET 5 и выше.

Области ограниченного выполнения используются в разных формах в среде CLR помимо аннотированного try блока, в частности критически важные финализаторы, выполняемые в классах, производных от CriticalFinalizerObject класса, и код, выполняемый с использованием метода ExecuteCodeWithGuaranteedCleanup.

Предварительная подготовка CER

CLR заранее подготавливает CER, чтобы избежать проблем с нехваткой памяти. Предварительная подготовка требуется, чтобы среда CLR не приводила к нехватке памяти во время JIT-компиляции или загрузки типов.

Разработчику необходимо указать, что кодовая область является CER:

  • Области и методы верхнего уровня CER в полной графе вызовов, к которым применён атрибут ReliabilityContractAttribute, готовятся заранее. ReliabilityContractAttribute может заявлять только гарантии Success или MayFail.

  • Предварительная подготовка не может выполняться для вызовов, которые не могут быть статически определены, например виртуальная диспетчеризация. PrepareMethod Используйте этот метод в этих случаях. При использовании метода ExecuteCodeWithGuaranteedCleanup атрибут PrePrepareMethodAttribute должен быть применен к коду очистки.

Ограничения

Пользователи ограничены в типе кода, который они могут писать в CER. Код не может вызвать исключение вне диапазона, например, как может произойти в результате следующих операций:

  • Явное выделение.

  • Бокс.

  • Получение блокировки.

  • Виртуальный вызов неподготовленных методов.

  • Вызов методов с контрактом надежности, который слабый или отсутствует.

В .NET Framework версии 2.0 эти ограничения являются рекомендациями. Диагностика предоставляется с помощью средств анализа кода.

Контракты надежности

Это ReliabilityContractAttribute настраиваемый атрибут, который документирует гарантии надежности и состояние повреждения заданного метода.

Гарантии надежности

Гарантии надежности, представленные значениями Cer перечисления, указывают степень надежности заданного метода:

  • MayFail. В исключительных условиях метод может потерпеть неудачу. В этом случае метод сообщает вызывающей процедуре, завершился ли он успешно или сбоем. Метод должен содержаться в CER, чтобы убедиться, что он может сообщать возвращаемое значение.

  • None. Метод, тип или сборка не имеет понятия CER и, скорее всего, не является безопасным для вызова в CER без существенного устранения повреждения состояния. Это не использует преимущества гарантий CER. В этом случае подразумевается следующее:

    1. В исключительных условиях метод может потерпеть неудачу.

    2. Метод может сообщить, а может и нет, о том, что он завершился ошибкой.

    3. Метод не предназначен для использования CER в наиболее вероятном сценарии.

    4. Если метод, тип или сборка не определены явно для успешного выполнения, он неявно определяется как 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 сразу перед блоком пробы. PrepareConstrainedRegions является членом класса поддержки компилятора RuntimeHelpers. Вызывайте PrepareConstrainedRegions непосредственно, ожидая его доступность через компиляторы.

Непрерываемые регионы

Непрерываемый регион группирует набор инструкций в CER.

В версии 2.0 .NET Framework, при наличии поддержки со стороны компилятора, пользовательский код создает непрерываемые области с надежным блоком try/catch/finally, который содержит пустой блок try/catch, предшествующий вызову метода PrepareConstrainedRegions.

Критически важный объект финализатора

Гарантирует, что сборка мусора CriticalFinalizerObject будет выполнять финализатор. При выделении финализатор и его граф вызовов подготавливаются заранее. Метод завершения выполняется в CER и должен соответствовать всем ограничениям, связанным с CER и методами завершения.

Типы, наследуемые от SafeHandle и CriticalHandle, гарантированно имеют выполнение финализатора в рамках CER. Реализуйте в производных классах ReleaseHandle и SafeHandle любой необходимый код для освобождения дескриптора.

Код не разрешен в CERs

Следующие операции не разрешены в CERs.

  • Явные выделения.

  • Получение блокировки.

  • Бокс.

  • Доступ к многомерному массиву.

  • Вызовы метода через рефлексию.

  • Enter или Lock.

  • Проверки безопасности. Не выполняйте требования, только связывайте их.

  • Isinst и Castclass для com-объектов и прокси-серверов

  • Получение или настройка полей в прозрачном прокси-сервере.

  • Сериализация.

  • Указатели функций и делегаты.

См. также