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


openGenericCERCall MDA

Примечание.

Эта статья относится к .NET Framework. Он не применяется к более новым реализациям .NET, включая .NET 6 и более поздние версии.

Помощник по отладке управляемого кода openGenericCERCall активируется, чтобы предупредить о том, что граф области ограниченного выполнения (CER) с переменными универсального типа в корневом методе обрабатывается во время JIT-компиляции или генерации образа в машинном коде и при этом как минимум одна из переменных универсального типа представляет собой тип ссылки на объект.

Симптомы

Код в области ограниченного выполнения не выполняется при прерывании потока или при выгрузке домена приложения.

Причина

Во время JIT-компиляции создание экземпляра типа ссылки на объект носит исключительно репрезентативный характер, поскольку полученный код будет общим, а каждая переменная типа ссылки на объект может быть любого типа ссылки на объект. Это позволяет предотвратить заблаговременную подготовку некоторых ресурсов времени выполнения.

В частности, методы с переменными универсального типа могут отложенным образом выделять ресурсы в фоновом режиме. Это записи универсального словаря. Например, для инструкции List<T> list = new List<T>(); , где T является переменная универсального типа, среда выполнения должна искать и, возможно, создавать точный экземпляр во время выполнения, например List<Object>, List<String>, и т. д. Этот процесс может завершаться сбоем по целому ряду причин, которые разработчик не может контролировать, например из-за нехватки памяти.

Этот помощник по отладке управляемого кода следует активировать только во время JIT-компиляции, а не при создании точного экземпляра.

Как правило, активация этого помощника по отладке управляемого кода вызвана сбоем области ограниченного выполнения для поврежденных экземпляров. Фактически среда выполнения не пытается реализовать область ограниченного выполнения в ситуации, в которой активируется этот помощник по отладке управляемого кода. Если разработчик использует общий экземпляр среды ограниченного выполнения, ошибки JIT-компиляции, ошибки загрузки универсальных типов или прерывания потоков в предполагаемой области ограниченного выполнения не перехватываются.

Разрешение

Не используйте переменные универсального типа, которые имеют тип ссылки на объект, в методах, которые могут содержать область ограниченного выполнения.

Влияние на среду выполнения

Этот помощник отладки управляемого кода не оказывает никакого влияния на среду CLR.

Выходные данные

Ниже приведен пример выходных данных из этого 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"

Настройка

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

Пример

Код в области ограниченного выполнения не выполняется.

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

См. также