OpenGenericCERCall-MDA
Hinweis
Dieser Artikel gilt für das .NET Framework. Sie gilt nicht für neuere Implementierungen von .NET, einschließlich .NET 6 und höherer Versionen.
Der openGenericCERCall
-MDA (Assistent für verwaltetes Debuggen) wird aktiviert, um zu warnen, dass ein CER-Diagramm mit generischen Typvariablen in der Stammmethode zum Zeitpunkt der JIT-Kompilierung oder der nativen Imagegenerierung verarbeitet wird und mindestens eine der generischen Typvariablen ein Objektverweistyp ist.
Symptome
CER-Code, der nicht ausgeführt wird, wenn ein Thread abgebrochen oder eine Anwendungsdomäne entladen wird.
Ursache
Zum Zeitpunkt der JIT-Kompilierung ist eine Instanziierung, die einen Objektverweistyp enthält, nur repräsentativ, da der resultierende Code freigegeben wird und jede Variable des Objektverweistyps ggf. ein beliebiger Objektverweistyp sein kann. Dies kann die Vorbereitung einiger Laufzeitressourcen im Voraus verhindern.
Methoden mit generischen Typvariablen können Ressourcen im Hintergrund verzögert zuordnen. Diese werden als generische Wörterbucheinträge bezeichnet. Bei der List<T> list = new List<T>();
ist T
eine generische Typvariable. Hier muss die Runtime die genaue Instanziierung zur Laufzeit nachschlagen und möglicherweise erstellen, z.B. List<Object>, List<String>
usw. Dies kann aus einer Vielzahl von Gründen fehlschlagen, die außerhalb der Kontrolle des Entwicklers liegen, z.B. fehlendem Arbeitsspeicher.
Dieser MDA sollte nur zum Zeitpunkt der JIT-Kompilierung aktiviert werden, und nicht bei einer genauen Instanziierung.
Wenn dieser MDA aktiviert wird, ist es wahrscheinlich, dass die CERs für fehlerhafte Instanziierungen nicht funktionsfähig sind. Die Common Language Runtime hat in der Tat nicht versucht, einen CER unter den Umständen zu implementieren, die zur Aktivierung der MDA geführt haben. Wenn der Entwickler eine freigegebene Instanziierung des CER verwendet, dann werden JIT-Kompilierungsfehler, Fehler beim Laden von Generics oder Threadabbrüche innerhalb des Bereichs des vorgesehenen CERs nicht abgefangen.
Lösung
Verwenden Sie keine generischen Typvariablen, die Objektverweistypen für Methoden sind, die möglicherweise eine CER enthalten.
Auswirkungen auf die Laufzeit
Dieser MDA hat keine Auswirkungen auf die CLR.
Ausgabe
Im Folgenden finden Sie ein Beispiel für die Ausgabe dieses 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"
Konfiguration
<mdaConfig>
<assistants>
<openGenericCERCall/>
</assistants>
</mdaConfig>
Beispiel
Der CER-Code wird nicht ausgeführt.
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.");
}
}
}