Udostępnij za pośrednictwem


openGenericCERCall MDA

Uwaga

Ten artykuł jest specyficzny dla programu .NET Framework. Nie ma zastosowania do nowszych implementacji platformy .NET, w tym .NET 6 i nowszych wersji.

Asystent openGenericCERCall zarządzanego debugowania jest aktywowany w celu ostrzeżenia, że wykres regionu wykonywania ograniczonego (CER) z ogólnymi zmiennymi typów w metodzie głównej jest przetwarzany w czasie kompilacji JIT lub generowania obrazu natywnego, a co najmniej jedna ze zmiennych typu ogólnego jest typem odwołania do obiektu.

Objawy

Kod CER nie jest uruchamiany, gdy wątek zostanie przerwany lub gdy domena aplikacji zostanie zwolniona.

Przyczyna

W czasie kompilacji JIT wystąpienie zawierające typ odwołania do obiektu jest reprezentatywne tylko dlatego, że wynikowy kod jest współużytkowany, a każda zmienna typu odwołania do obiektu może być dowolnym typem odwołania do obiektu. Może to uniemożliwić przygotowanie niektórych zasobów w czasie wykonywania z wyprzedzeniem.

W szczególności metody ze zmiennymi typów ogólnych mogą leniwie przydzielać zasoby w tle. Są one nazywane ogólnymi wpisami słownika. Na przykład w przypadku instrukcji List<T> list = new List<T>(); , w której T jest zmienną typu ogólnego, środowisko uruchomieniowe musi wyszukać i ewentualnie utworzyć dokładne wystąpienie w czasie wykonywania, na przykład , List<Object>, List<String>i tak dalej. Może to zakończyć się niepowodzeniem z różnych powodów poza kontrolą dewelopera, takich jak brak pamięci.

To rozwiązanie MDA powinno być aktywowane tylko w czasie kompilacji JIT, a nie w przypadku dokładnego utworzenia wystąpienia.

Po aktywowaniu tego MDA prawdopodobne objawy są takie, że ceRs nie działają w przypadku nieprawidłowych wystąpień. W rzeczywistości środowisko uruchomieniowe nie próbowało zaimplementować cer w okolicznościach, które spowodowały aktywację MDA. Jeśli więc deweloper używa współużytkowanego wystąpienia CER, błędy kompilacji JIT, błędy ładowania typów ogólnych lub przerwania wątków w regionie zamierzonego CER nie są przechwytywane.

Rozwiązanie

Nie należy używać zmiennych typów ogólnych, które są typu odwołania do obiektu dla metod, które mogą zawierać CER.

Wpływ na środowisko uruchomieniowe

Ta usługa MDA nie ma wpływu na CLR.

Wyjście

Poniżej przedstawiono przykładowe dane wyjściowe z tego rozwiązania 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"

Konfigurowanie

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

Przykład

Kod CER nie jest wykonywany.

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

Zobacz też