openGenericCERCall MDA
Notitie
Dit artikel is specifiek voor .NET Framework. Dit geldt niet voor nieuwere implementaties van .NET, waaronder .NET 6 en nieuwere versies.
De openGenericCERCall
assistent voor beheerde foutopsporing wordt geactiveerd om te waarschuwen dat een cer-grafiek (constrained execution region) met algemene typevariabelen bij de hoofdmethode wordt verwerkt tijdens het genereren van JIT-compilatie of systeemeigen installatiekopieën. Ten minste één van de algemene typevariabelen is een objectverwijzingstype.
Symptomen
CER-code wordt niet uitgevoerd wanneer een thread wordt afgebroken of wanneer een toepassingsdomein wordt verwijderd.
Oorzaak
Tijdens de compilatietijd van JIT is een instantiëring met een objectverwijzingstype alleen representatief omdat de resulterende code wordt gedeeld en elk van de variabelen van het objectverwijzingstype elk objectverwijzingstype kan zijn. Dit kan voorkomen dat bepaalde runtime-resources van tevoren worden voorbereid.
Met name methoden met algemene typevariabelen kunnen resources op de achtergrond lazily toewijzen. Deze worden algemene woordenlijstvermeldingen genoemd. Voor de instructie List<T> list = new List<T>();
waarbij T
bijvoorbeeld een algemene typevariabele is, moet de runtime de exacte instantiëring tijdens runtime List<Object>, List<String>
opzoeken en mogelijk maken. Dit kan om verschillende redenen mislukken buiten de controle van de ontwikkelaar, zoals onvoldoende geheugen.
Deze MDA mag alleen worden geactiveerd tijdens de compilatietijd van JIT, niet wanneer er een exacte instantiëring is.
Wanneer deze MDA wordt geactiveerd, zijn de waarschijnlijke symptomen dat CER's niet functioneel zijn voor de slechte instantiëringen. In feite heeft de runtime niet geprobeerd een CER te implementeren onder de omstandigheden waardoor de MDA werd geactiveerd. Dus als de ontwikkelaar gebruikmaakt van een gedeelde instantiëring van de CER, worden JIT-compilatiefouten, generieken type laadfouten of threads in de regio van de beoogde CER niet gevangen.
Oplossing
Gebruik geen algemene typevariabelen die van het objectverwijzingstype zijn voor methoden die mogelijk een CER bevatten.
Effect op de runtime
Deze MDA heeft geen effect op de CLR.
Uitvoer
Hier volgt een voorbeeld van uitvoer van deze 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"
Configuratie
<mdaConfig>
<assistants>
<openGenericCERCall/>
</assistants>
</mdaConfig>
Opmerking
De CER-code wordt niet uitgevoerd.
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.");
}
}
}