openGenericCERCall MDA
Kommentar
Den här artikeln är specifik för .NET Framework. Det gäller inte för nyare implementeringar av .NET, inklusive .NET 6 och senare versioner.
Den openGenericCERCall
hanterade felsökningsassistenten aktiveras för att varna för att en cer-graf (begränsad körningsregion) med generiska typvariabler vid rotmetoden bearbetas vid JIT-kompilering eller intern bildgenereringstid och att minst en av de generiska typvariablerna är en objektreferenstyp.
Symtom
CER-kod körs inte när en tråd avbryts eller när en programdomän tas bort.
Orsak
Vid JIT-kompilering är en instansiering som innehåller en objektreferenstyp endast representativ eftersom den resulterande koden delas och var och en av objektreferenstypvariablerna kan vara vilken objektreferenstyp som helst. Detta kan förhindra förberedelse av vissa körningsresurser i förväg.
I synnerhet kan metoder med generiska typvariabler lätt allokera resurser i bakgrunden. Dessa kallas allmänna ordlisteposter. För instruktionen List<T> list = new List<T>();
där T
är en allmän typvariabel måste körningen till exempel leta upp och eventuellt skapa den exakta instansieringen vid körning, List<Object>, List<String>
till exempel , och så vidare. Detta kan misslyckas av en mängd olika orsaker utöver utvecklarens kontroll, till exempel att minnet tar slut.
Denna MDA bör endast aktiveras vid JIT-kompilering, inte när det finns en exakt instansiering.
När denna MDA aktiveras är de troliga symptomen att CER inte fungerar för de dåliga instansiationerna. I själva verket har körningen inte försökt implementera en CER under de omständigheter som gjorde att MDA aktiverades. Så om utvecklaren använder en delad instansiering av CER fångas inte JIT-kompileringsfel, inläsningsfel av generisk typ eller trådfel inom den avsedda CER-regionen.
Åtgärd
Använd inte allmänna typvariabler som är av objektreferenstyp för metoder som kan innehålla en CER.
Effekt på körningen
Denna MDA har ingen effekt på CLR.
Output
Följande är ett exempel på utdata från denna 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>
Exempel
CER-koden körs inte.
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.");
}
}
}