Teilen über


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 von T 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 von T verwendet werden, verhindert das Entladen.

  • Ein statischer Verweis auf T durch einen anderen dynamisch definierten T1-Typ, der für ausgeführten Code weiterhin erreichbar ist. T1 kann beispielsweise von T abgeleitet werden, oder T kann den Typ eines Parameters in einer Methode von T1 darstellen.

  • Ein ByRef für ein statisches Feld, das zu T gehört.

  • Eine RuntimeTypeHandle-, RuntimeFieldHandle- oder RuntimeMethodHandle-Struktur, die auf T oder eine Komponente von T 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ür T kann beispielsweise von einem Arraytyp abgerufen werden, dessen Elementtyp T ist, oder von einem generischen Typ mit T als Typargument.

  • Eine M-Methode in der Aufrufliste eines beliebigen Threads, bei der M eine Methode von T 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.

Weitere Informationen