Regiões de execução restritas
Uma região de execução restrita (CER) faz parte de um mecanismo para criar código gerenciado confiável. Um CER define uma área na qual o Common Language Runtime (CLR) é impedido de lançar exceções fora de banda que impediriam que o código na área fosse executado em sua totalidade. Dentro dessa região, o código do usuário é impedido de executar código que resultaria no lançamento de exceções fora de banda. O PrepareConstrainedRegions método deve preceder imediatamente um try
bloco e marcar catch
, finally
e fault
blocos 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 o thread aborta para o código que está sendo executado em um CER.
Importante
O CER só é suportado no .NET Framework. Este artigo não se aplica ao .NET Core ou .NET 5 e superior.
Regiões de execução restritas são usadas em diferentes formas no CLR, além de um bloco anotado try
, notavelmente finalizadores críticos executados em classes derivadas da CriticalFinalizerObject classe e código executado usando o ExecuteCodeWithGuaranteedCleanup método.
Preparação Antecipada CER
O CLR prepara CERs com antecedência para evitar condições de falta de memória. A preparação antecipada é necessária para que o CLR não cause uma condição de falta de memória durante a compilação just-in-time ou o carregamento do tipo.
O desenvolvedor é obrigado a indicar que uma região de código é um CER:
A região CER de nível superior e os métodos no gráfico de chamada completo que têm o ReliabilityContractAttribute atributo aplicado são preparados com antecedência. O ReliabilityContractAttribute Estado só pode garantir garantias de Success ou MayFail.
A preparação antecipada não pode ser executada para chamadas que não podem ser determinadas estaticamente, como o envio virtual. Use o PrepareMethod método nesses casos. Ao usar o ExecuteCodeWithGuaranteedCleanup método, o PrePrepareMethodAttribute atributo deve ser aplicado ao código de limpeza.
Restrições
Os usuários são limitados 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.
Adquirir uma fechadura.
Chamando métodos despreparados virtualmente.
Chamando métodos com um contrato de confiabilidade fraco ou inexistente.
No .NET Framework versão 2.0, essas restrições são diretrizes. Os diagnósticos são fornecidos por meio de ferramentas de análise de código.
Contratos de Fiabilidade
O ReliabilityContractAttribute é um atributo personalizado que documenta as garantias de confiabilidade e o estado de corrupção de um determinado método.
Garantias de Fiabilidade
As garantias de fiabilidade, representadas por Cer valores de enumeração, indicam o grau de fiabilidade de um determinado método:
MayFail. Em condições excecionais, o método pode falhar. Nesse caso, o método relata de volta para o método de chamada se ele foi bem-sucedido ou falhou. O método deve estar contido em uma RCE para garantir que ela possa relatar o valor de retorno.
None. O método, tipo ou montagem não tem conceito de RCE e provavelmente não é seguro chamar dentro de uma RCE sem mitigação substancial da corrupção estatal. Não tira partido das garantias da CER. Isto implica o seguinte:
Em condições excecionais, o método pode falhar.
O método pode ou não relatar que falhou.
O método não é escrito para usar um CER, o cenário mais provável.
Se um método, tipo ou assembly não for explicitamente identificado como bem-sucedido, ele será implicitamente identificado como None.
Success. Em condições excecionais, o sucesso do método é garantido. Para atingir esse nível de confiabilidade, você deve sempre construir um CER em torno do método que é chamado, mesmo quando ele é chamado de dentro de uma região não-CER. Um método é bem-sucedido se realizar o que se pretende, embora o sucesso possa ser visto subjetivamente. Por exemplo, marcar Contar com
ReliabilityContractAttribute(Cer.Success)
implica que, quando ele é executado sob 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 CompareExchange método também é marcado como sucesso, com o entendimento de que o sucesso pode significar que o valor não pode ser substituído por um novo valor devido a uma condição de raça. O ponto-chave é que o método se comporta da maneira como está documentado para se comportar, e o código CER não precisa ser escrito para esperar qualquer comportamento incomum além do que o código correto, mas não confiável, pareceria.
Níveis de corrupção
Os níveis de corrupção, representados por Consistency valores de enumeração, indicam quanto estado pode estar corrompido em um determinado ambiente:
MayCorruptAppDomain. Em condições excecionais, o Common Language Runtime (CLR) não oferece garantias em relação à consistência de estado no domínio do aplicativo atual.
MayCorruptInstance. Em condições excecionais, o método é garantido para limitar a corrupção estatal à instância atual.
MayCorruptProcess, Em condições excecionais, o CLR não dá garantias quanto à coerência do Estado; ou seja, a condição pode corromper o processo.
WillNotCorruptState. Em condições excecionais, o método é garantido para não corromper o Estado.
Confiabilidade tentar/capturar/finalmente
A fiabilidade try/catch/finally
é um mecanismo de tratamento de exceções com o mesmo nível de garantias de previsibilidade que a versão não gerida. O catch/finally
bloco é o CER. Os métodos no bloco exigem preparação prévia e devem ser ininterruptos.
No .NET Framework versão 2.0, o código informa o tempo de execução que uma tentativa é confiável chamando PrepareConstrainedRegions imediatamente antes de um bloco try. PrepareConstrainedRegions é membro de , uma classe de suporte do RuntimeHelperscompilador. Ligue PrepareConstrainedRegions diretamente aguardando sua disponibilidade através de compiladores.
Regiões ininterruptas
Uma região ininterrupta agrupa um conjunto de instruções em um CER.
No .NET Framework versão 2.0, aguardando disponibilidade por meio do suporte ao compilador, o código do usuário cria regiões ininterruptas com um try/catch/finally confiável que contém um bloco try/catch vazio precedido por uma PrepareConstrainedRegions chamada de método.
Objeto finalizador crítico
A CriticalFinalizerObject garante que a coleta de lixo executará o finalizador. Após a alocação, o finalizador e seu gráfico de chamada são preparados com antecedência. O método finalizador é executado em um CER, e deve obedecer a todas as restrições em CERs e finalizadores.
Todos os tipos herdam e CriticalHandle têm a garantia de ter seu finalizador executado dentro de SafeHandle um CER. Implemente ReleaseHandle em SafeHandle classes derivadas para executar qualquer código necessário para liberar o identificador.
Código não permitido em RCE
Não são permitidas as seguintes operações nas RCE:
Alocações explícitas.
Adquirir uma fechadura.
Boxe.
Acesso a matrizes multidimensionais.
O método chama através da reflexão.
Verificações de segurança. Não execute demandas, apenas vincule demandas.
Obter ou definir campos em um proxy transparente.
Serialização.
Ponteiros de função e delegados.