Compartilhar via


Regiões de execução restrita

Uma CER (região de execução restrita) faz parte de um mecanismo de criação de código gerenciado confiável. Uma CER define uma área na qual o CLR (Common Language Runtime) é impedido de gerar exceções fora de banda que impediriam a execução do código na área em sua totalidade. Nessa região, o código do usuário é restrito de executar um código que poderá resultar na geração de exceções fora de banda. O PrepareConstrainedRegions método deve preceder imediatamente um try bloco e marca os blocos catch, finally e fault como regiões de execução restritas. Uma vez marcado como uma região restrita, o código só deve chamar outro código com contratos de confiabilidade fortes e o código não deve alocar ou fazer chamadas virtuais para métodos não preparados ou não confiáveis, a menos que o código esteja preparado para lidar com falhas. O CLR atrasa as anulações de thread do código que está sendo executado em uma CER.

Importante

O CER só tem suporte no .NET Framework. Este artigo não se aplica ao .NET Core ou ao .NET 5 e posteriores.

Regiões de execução restrita são usadas de diferentes formas no CLR, além de um bloco anotado try, notadamente finalizadores críticos em execução em classes derivadas da classe CriticalFinalizerObject e código executado usando o método ExecuteCodeWithGuaranteedCleanup.

Preparação antecipada do CER

O CLR prepara as CERs com antecedência para evitar condições de memória insuficiente. A preparação antecipada é necessária para que a CLR não cause uma condição de memória insuficiente durante a compilação Just-In-Time ou o carregamento de tipo.

O desenvolvedor precisa indicar que uma região de código é uma CER.

Restrições

Os usuários são restringidos no tipo de código que podem escrever em um CER. O código não pode causar uma exceção fora de banda, como pode resultar das seguintes operações:

  • Alocação explícita.

  • Boxe.

  • Aquisição de um bloqueio.

  • Chamada virtual a métodos não preparados.

  • Chamada a métodos com um contrato de confiabilidade fraca ou não existente.

No .NET Framework versão 2.0, essas restrições são diretrizes. O diagnóstico é fornecido por meio de ferramentas de análise de código.

Contratos de confiabilidade

É ReliabilityContractAttribute um atributo personalizado que documenta as garantias de confiabilidade e o estado de corrupção de um determinado método.

Garantias de confiabilidade

As garantias de confiabilidade, representadas por Cer valores de enumeração, indicam o grau de confiabilidade de um determinado método:

  • MayFail. Em condições excepcionais, o método pode falhar. Nesse caso, o método retorna ao método de chamada se ele foi bem-sucedido ou falhou. O método deve estar contido em um CER para garantir que ele possa relatar o valor retornado.

  • None. O método, tipo ou assembly não tem nenhum conceito de uma CER e, provavelmente, não é seguro de ser chamado em uma CER sem uma mitigação significativa dos danos ao estado. Ele não toma proveito das garantias CER. Isso significa o seguinte:

    1. Em condições excepcionais, o método pode falhar.

    2. O método poderá ou não relatar sua falha.

    3. O método não é escrito para usar um CER, o cenário mais provável.

    4. Se um método, tipo ou assembly não for identificado explicitamente para ter êxito, ele será identificado implicitamente como None.

  • Success. Em condições excepcionais, é garantido que o método tenha êxito. Para atingir esse nível de confiabilidade, você sempre deve construir um CER em torno do método chamado, mesmo quando ele é chamado de dentro de uma região que não seja CER. Um método é bem-sucedido se ele realiza o que se pretende, embora o sucesso possa ser exibido subjetivamente. Por exemplo, marcar Contagem com ReliabilityContractAttribute(Cer.Success) implica que, quando ele é executado em um CER, ele sempre retorna uma contagem do número de elementos no ArrayList e nunca pode deixar os campos internos em um estado indeterminado. No entanto, o método CompareExchange é marcado como êxito também, com o entendimento de que o êxito pode indicar que o valor não pode ser substituído por um novo valor devido a uma condição de corrida. O ponto chave é que o método se comporta da forma que está documentado, e não é necessário escrever o código CER para antecipar qualquer comportamento incomum além do que seria um código correto, mas não confiável.

Níveis de corrupção

Os níveis de corrupção, representados por Consistency valores de enumeração, indicam o grau de corrupção que o estado pode sofrer em um determinado ambiente.

  • MayCorruptAppDomain. Em condições excepcionais, o CLR (Common Language Runtime) não garante a consistência de estado no domínio do aplicativo atual.

  • MayCorruptInstance. Em condições excepcionais, o método garante a limitação da corrupção de estado à instância atual.

  • MayCorruptProcess, em condições excepcionais, o CLR não garante a consistência do estado; ou seja, a condição pode corromper o processo.

  • WillNotCorruptState. Em condições excepcionais, o método tem a garantia de não corromper o estado.

Confiabilidade try/catch/finally

A confiabilidade try/catch/finally é um mecanismo de tratamento de exceção com o mesmo nível de garantias de previsibilidade que a versão não gerenciada. O bloco catch/finally é a CER. Os métodos no bloco exigem preparação antecipada e devem ser ininterruptos.

No .NET Framework versão 2.0, o código informa o runtime de que um try é confiável chamando PrepareConstrainedRegions imediatamente antes de um bloco try. PrepareConstrainedRegions é membro de uma classe de suporte ao compilador RuntimeHelpers. Chame PrepareConstrainedRegions diretamente, pendente sua disponibilidade por meio dos compiladores.

Regiões não interinterruptas

Uma região não interinterrupta agrupa um conjunto de instruções em um CER.

No .NET Framework versão 2.0, pendente disponibilidade por meio do suporte de compilador, o código do usuário cria regiões não interrompíveis com um try/catch/finally confiável que contém um bloco try/catch vazio precedido por uma chamada de método PrepareConstrainedRegions.

Objeto Finalizador Crítico

Um CriticalFinalizerObject garante que a coleta de lixo executará o finalizador. Após a alocação, o finalizador e seu grafo de chamadas são preparados com antecedência. O método do finalizador é executado em uma CER e deve respeitar todas as restrições nas CERs e nos finalizadores.

Os tipos que herdam SafeHandle e CriticalHandle têm a garantia de que seu finalizador será executado em uma CER. Implemente ReleaseHandle nas classes derivadas SafeHandle para executar qualquer código que deve liberar o identificador.

Código não permitido em CERs

As seguintes operações não são permitidas em CERs:

  • Alocações explícitas.

  • Aquisição de um bloqueio.

  • Boxe.

  • Acesso de matriz multidimensional.

  • Chamadas de método por meio de reflexão.

  • Enter ou Lock.

  • Verificações de segurança. Não execute demandas, apenas demandas de link.

  • Isinst e Castclass para objetos e proxies COM

  • Obtendo ou definindo campos em um proxy transparente.

  • Serialização.

  • Ponteiros de função e representantes.

Consulte também