Entladbare Assemblys für die dynamische Typgenerierung
Bei entladbaren Assemblys handelt es sich um dynamische Assemblys, die entladen werden können, ohne die Anwendungsdomäne zu entladen, in der sie erstellt wurden. Der verwaltete und nicht verwaltete Speicher, der von einer entladbaren Assembly und den darin enthaltenen Typen verwendet wurde, kann wieder freigegeben werden. Informationen wie der Name der Assembly werden aus den internen Tabellen entfernt.
Verwenden Sie zum Aktivieren der Entladung das AssemblyBuilderAccess.RunAndCollect-Flag, wenn Sie eine dynamische Assembly erstellen. Die Assembly ist flüchtig (d. h. sie kann nicht gespeichert werden) und unterliegt den Einschränkungen, die im Abschnitt Einschränkungen bei entladbaren Assemblys beschrieben werden. Die Common Language Runtime (CLR) entlädt eine entladbare Assembly automatisch, wenn Sie alle Objekte freigeben, die der Assembly zugeordnet sind. In jeder anderen Hinsicht werden entladbare Assemblys genau wie andere dynamische Assemblys erstellt und verwendet.
Lebensdauer von entladbaren Assemblys
Die Lebensdauer einer entladbaren Assembly wird durch das Vorhandensein der Verweise auf die enthaltenen Typen und auf die Objekte, die aus diesen Typen erstellt werden, gesteuert. Die Common Language Runtime entlädt eine Assembly nicht, solange mindestens eins der folgenden Objekte vorhanden ist (bei T
handelt es sich um einen beliebigen Typ, der in der Assembly definiert wird):
Eine Instanz von
T
.Eine Instanz eines Arrays von
T
.Eine Instanz eines generischen Typs, der über
T
als Typargument verfügt. Dies schließt generische Auflistungen vonT
ein, auch wenn diese Auflistung leer ist.Eine Instanz von Type oder TypeBuilder, die
T
darstellt.Wichtig
Sie müssen alle Objekte freigeben, die Teile der Assembly darstellen. Die ModuleBuilder-Klasse, die
T
definiert, behält einen Verweis auf TypeBuilder bei, und das AssemblyBuilder-Objekt behält einen Verweis auf ModuleBuilder bei. Die Verweise auf diese Objekte müssen ebenfalls freigegeben werden. Auch das Vorhandensein einer LocalBuilder- oder ILGenerator-Klasse, die bei der Erstellung vonT
verwendet werden, verhindert das Entladen.Ein statischer Verweis auf
T
durch einen anderen dynamisch definiertenT1
-Typ, der für ausgeführten Code weiterhin erreichbar ist.T1
kann beispielsweise vonT
abgeleitet werden, oderT
kann den Typ eines Parameters in einer Methode vonT1
darstellen.Ein
ByRef
für ein statisches Feld, das zuT
gehört.Eine RuntimeTypeHandle-, RuntimeFieldHandle- oder RuntimeMethodHandle-Struktur, die auf
T
oder eine Komponente vonT
verweist.Eine Instanz eines beliebigen Reflektionsobjekts, das indirekt oder direkt verwendet werden kann, um auf das Type-Objekt zuzugreifen, das
T
darstellt. Das Type-Objekt fürT
kann beispielsweise von einem Arraytyp abgerufen werden, dessen ElementtypT
ist, oder von einem generischen Typ mitT
als Typargument.Eine
M
-Methode in der Aufrufliste eines beliebigen Threads, bei derM
eine Methode vonT
oder eine Methode auf Modulebene darstellt, die in der Assembly definiert ist.Ein Delegat für eine statische Methode, der in einem Modul der Assembly definiert wird.
Wenn ein Element aus dieser Liste für einen Typ oder eine Methode in der Assembly vorhanden ist, kann die Runtime die Assembly nicht entladen.
Hinweis
Die Runtime entlädt die Assembly nicht, bevor Finalizer für alle Elemente in der Liste ausgeführt wurden.
Zum Nachverfolgen der Lebensdauer sollte ein konstruierter generischer Typ wie List<int>
(in C#) oder List(Of Integer)
(in Visual Basic), der bei der Generierung einer entladbaren Assembly erstellt und verwendet wird, entweder in der Assembly, die die generische Typdefinition enthält, oder in einer Assembly, die die Definition von einem seiner Typargumente enthält, definiert werden. Die genaue Assembly, die verwendet wird, ist ein Implementierungsdetail und kann sich noch ändern.
Einschränkungen bei entladbaren Assemblys
Für entladbare Assemblys gelten folgende Einschränkungen:
Statische Verweise
Die Typen in einer gewöhnlichen dynamischen Assembly können keine statischen Verweise auf Typen enthalten, die in einer entladbaren Assembly definiert sind. Wenn Sie beispielsweise einen normalen Typ definieren, der von einem Typ in einer entladbaren Assembly erbt, wird eine NotSupportedException-Ausnahme ausgelöst. Ein Typ in einer entladbaren Assembly kann statische Verweise auf einen Typ in einer anderen entladbaren Assembly enthalten, dadurch wird jedoch die Lebensdauer der Assembly, auf die verweisen wird, auf die Lebensdauer der verweisenden Assembly erweitert.
Für entladbare Assemblys gelten in.NET Framework folgende Einschränkungen:
COM-Interop
In einer entladbaren Assembly können keine COM-Schnittstellen definiert werden, und Instanzen von Typen in einer entladbaren Assembly können nicht in COM-Objekte konvertiert werden. Ein Typ in einer entladbaren Assembly kann nicht als COM Callable Wrapper (CCW) oder Runtime Callable Wrapper (RCW) verwendet werden. Typen in entladbaren Assemblys können jedoch Objekte verwenden, die COM-Schnittstellen implementieren.
Plattformaufruf
Methoden mit dem DllImportAttribute-Attribut können nicht kompiliert werden, wenn sie in einer entladbaren Assembly definiert werden. Die OpCodes.Calli-Anweisung kann nicht in der Implementierung eines Typs in einer entladbaren Assembly verwendet werden, und solche Typen können nicht an nicht verwalteten Code gemarshallt werden. Sie können jedoch Aufrufe in nativem Code durchführen, indem Sie einen Einstiegspunkt verwenden, der in einer nicht entladbaren Assembly deklariert ist.
Marshalling
Objekte (insbesondere Delegate), die in entladbaren Assemblys definiert sind, können nicht gemarshallt werden. Diese Einschränkung gilt für alle flüchtig ausgegebenen Typen.
Laden von Assemblys
Die Reflexionsausgabe stellt den einzigen Mechanismus dar, der zum Laden von entladbaren Assemblys unterstützt wird. Assemblys, die mithilfe einer anderen Methode zum Laden von Assemblys geladen werden, können nicht entladen werden.
Kontextgebundene Objekte
Kontextstatische Variablen werden nicht unterstützt. Typen in einer entladbaren Assembly können ContextBoundObject nicht erweitern. Der Code in entladbaren Assemblys kann jedoch in kontextgebundenen Objekten verwendet werden, die an anderer Stelle definiert werden.
Threadstatische Daten
Threadstatische Variablen werden nicht unterstützt.
Die folgenden Einschränkungen gelten für entladbare Assemblys in .NET Framework und .NET-Versionen vor .NET 9:
Statische Felder mit
FixedAddressValueTypeAttribute
Auf statische Felder, die in entladbaren Assemblys definiert sind, kann das FixedAddressValueTypeAttribute-Attribut nicht angewandt werden.