openGenericCERCall MDA |
Nota
Este artigo é específico do .NET Framework. Ele não se aplica a implementações mais recentes do .NET, incluindo o .NET 6 e versões posteriores.
O openGenericCERCall
assistente de depuração gerenciado é ativado para avisar que um gráfico de região de execução restrita (CER) com variáveis de tipo genéricas no método raiz está sendo processado no tempo de compilação JIT ou geração de imagem nativa e pelo menos uma das variáveis de tipo genéricas é um tipo de referência de objeto.
Sintomas
O código CER não é executado quando um thread é abortado ou quando um domínio de aplicativo é descarregado.
Motivo
No momento da compilação JIT, uma instanciação contendo um tipo de referência de objeto só é representativa porque o código resultante é compartilhado e cada uma das variáveis de tipo de referência de objeto pode ser qualquer tipo de referência de objeto. Isso pode impedir a preparação de alguns recursos de tempo de execução com antecedência.
Em particular, métodos com variáveis de tipo genéricas podem alocar preguiçosamente recursos em segundo plano. Estas são referidas como entradas genéricas de dicionário. Por exemplo, para a instrução List<T> list = new List<T>();
onde T
é uma variável de tipo genérica, o tempo de execução deve procurar e possivelmente criar a instanciação exata em tempo de execução, por exemplo, List<Object>, List<String>
e assim por diante. Isso pode falhar por uma variedade de razões além do controle do desenvolvedor, como ficar sem memória.
Este MDA só deve ser ativado no momento da compilação JIT, não quando há uma instanciação exata.
Quando este MDA é ativado, os sintomas prováveis são que CERs não são funcionais para as instanciações ruins. Na verdade, o tempo de execução não tentou implementar um CER nas circunstâncias que causaram a ativação do MDA. Portanto, se o desenvolvedor usar uma instanciação compartilhada do CER, erros de compilação JIT, erros de carregamento de tipo genérico ou abortamentos de thread dentro da região do CER pretendido não serão detetados.
Resolução
Não use variáveis de tipo genéricas que são do tipo de referência de objeto para métodos que podem conter um CER.
Efeito no tempo de execução
Este MDA não tem efeito sobre o CLR.
Saída
Segue-se um exemplo de saída deste MDA:
Method 'GenericMethodWithCer', which contains at least one constrained execution region, cannot be prepared automatically since it has one or more unbound generic type parameters.
The caller must ensure this method is prepared explicitly at run time prior to execution.
method name="GenericMethodWithCer"
declaringType name="OpenGenericCERCall"
Configuração
<mdaConfig>
<assistants>
<openGenericCERCall/>
</assistants>
</mdaConfig>
Exemplo
O código CER não é executado.
using System;
using System.Collections.Generic;
using System.Runtime.CompilerServices;
class Program
{
static void Main(string[] args)
{
CallGenericMethods();
}
static void CallGenericMethods()
{
// This call is correct. The instantiation of the method
// contains only nonreference types.
MyClass.GenericMethodWithCer<int>();
// This call is incorrect. A shared version of the method that
// cannot be completely analyzed will be JIT-compiled. The
// MDA will be activated at JIT-compile time, not at run time.
MyClass.GenericMethodWithCer<String>();
}
}
class MyClass
{
public static void GenericMethodWithCer<T>()
{
RuntimeHelpers.PrepareConstrainedRegions();
try
{
}
finally
{
// This is the start of the CER.
Console.WriteLine("In finally block.");
}
}
}