Partager via


openGenericCERCall MDA

Note

Cet article est spécifique à .NET Framework. Elle ne s’applique pas aux implémentations plus récentes de .NET, notamment .NET 6 et versions ultérieures.

L’Assistant openGenericCERCall débogage managé est activé pour avertir qu’un graphique de région d’exécution contrainte (CER) avec des variables de type génériques au niveau de la méthode racine est traité au moment de la compilation JIT ou de la génération d’images native et qu’au moins l’une des variables de type générique est un type de référence d’objet.

Symptômes

Le code CER ne s’exécute pas lorsqu’un thread est abandonné ou lorsqu’un domaine d’application est déchargé.

La cause

Au moment de la compilation JIT, une instanciation contenant un type de référence d’objet n’est représentative que parce que le code résultant est partagé, et chacune des variables de type de référence d’objet peut être n’importe quel type de référence d’objet. Cela peut empêcher la préparation de certaines ressources d’exécution à l’avance.

En particulier, les méthodes avec des variables de type générique peuvent allouer automatiquement des ressources en arrière-plan. Il s’agit d’entrées de dictionnaire générique. Par exemple, pour l’instruction List<T> list = new List<T>();T est une variable de type générique, le runtime doit rechercher et éventuellement créer l’instanciation exacte au moment de l’exécution, par exemple, List<Object>, List<String>et ainsi de suite. Cela peut échouer pour diverses raisons au-delà du contrôle du développeur, comme l’épuisement de la mémoire.

Ce MDA ne doit être activé qu’au moment de la compilation JIT, et non lorsqu’il existe une instanciation exacte.

Lorsque ce MDA est activé, les symptômes probables sont que les CER ne sont pas fonctionnels pour les instanciations incorrectes. En fait, le runtime n’a pas tenté d’implémenter un cer dans les circonstances qui ont provoqué l’activation de l’authentification MDA. Par conséquent, si le développeur utilise une instanciation partagée du cer, les erreurs de compilation JIT, les erreurs de chargement de type générique ou les abandons de threads dans la région du cer prévu ne sont pas interceptés.

Résolution

N’utilisez pas de variables de type générique qui sont de type référence d’objet pour les méthodes qui peuvent contenir un cer.

Effet sur le runtime

Ce MDA n’a aucun effet sur le CLR.

Output

Voici un exemple de sortie de cette 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 runtime prior to execution.
method name="GenericMethodWithCer"
declaringType name="OpenGenericCERCall"

Paramétrage

<mdaConfig>
  <assistants>
    <openGenericCERCall/>
  </assistants>
</mdaConfig>

Example

Le code CER n’est pas exécuté.

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 runtime.
        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.");
        }
    }
}

Voir aussi