Condividi tramite


Assemblaggi collezionabili per la generazione di tipi dinamici

Gli assembly collezionabili sono assembly dinamici che possono essere scaricati senza rimuovere il dominio dell'applicazione in cui sono stati creati. Tutta la memoria gestita e non gestita utilizzata da un assembly recuperabile e dai tipi che esso contiene può essere recuperata. Le informazioni, ad esempio il nome dell'assembly, vengono rimosse dalle tabelle interne.

Per abilitare lo scaricamento, usare il AssemblyBuilderAccess.RunAndCollect flag quando si crea un assembly dinamico. L'assemblaggio è temporaneo, ovvero non può essere salvato, ed è soggetto alle limitazioni descritte nella sezione Restrizioni sugli assemblaggi raccoglibili. Il common language runtime (CLR) scarica in modo automatico un assembly raccoglibile quando si rilasciano tutti gli oggetti associati all'assembly. In tutti gli altri rispetti, gli assembly collettabili vengono creati e usati nello stesso modo degli altri assembly dinamici.

Durata delle assembly collezionabili

La durata di un assembly collezionabile è controllata dall'esistenza dei riferimenti ai tipi che contiene e dagli oggetti creati da tali tipi. Common Language Runtime non scarica un assembly purché esista uno o più dei seguenti tipi (T è qualsiasi tipo definito nell'assembly):

  • Istanza di T.

  • Istanza di una matrice di T.

  • Istanza di un tipo generico con T come uno dei relativi argomenti di tipo. Sono incluse raccolte generiche di T, anche se tale raccolta è vuota.

  • Istanza di Type o TypeBuilder che rappresenta T.

    Importante

    È necessario rilasciare tutti gli oggetti che rappresentano parti dell'assembly. L'oggetto ModuleBuilder che definisce T mantiene un riferimento all'oggetto TypeBuilder, e l'oggetto AssemblyBuilder mantiene un riferimento all'oggetto ModuleBuilder, pertanto è necessario rilasciare i riferimenti a questi oggetti. Anche l'esistenza di un LocalBuilder o di un ILGenerator utilizzato nella costruzione di T impedisce il scarico.

  • Riferimento statico a T da un altro tipo T1 definito in modo dinamico che è ancora raggiungibile eseguendo il codice. Ad esempio, T1 può derivare da To T potrebbe essere il tipo di un parametro in un metodo di T1.

  • Un riferimento ByRef a un campo statico che appartiene a T.

  • Oggetto RuntimeTypeHandle, RuntimeFieldHandleo RuntimeMethodHandle che fa riferimento a T o a un componente di T.

  • Un'istanza di qualsiasi oggetto di riflessione che possa essere utilizzata sia indirettamente che direttamente per accedere all'oggetto Type che rappresenta T. Ad esempio, l'oggetto Type per T può essere ottenuto da un tipo di matrice il cui tipo di elemento è To da un tipo generico con T come argomento di tipo.

  • Un metodo M nello stack di chiamate di qualsiasi thread, dove M è un metodo di T o un metodo a livello di modulo T definito nell'assembly.

  • Delegato a un metodo statico definito in un modulo dell'assembly.

Se esiste un solo elemento dell'elenco per un solo tipo o un metodo nell'assembly, il runtime non può scaricare l'assembly.

Annotazioni

Il runtime non scarica il pacchetto solo dopo che i finalizzatori sono stati eseguiti per tutti gli elementi nell'elenco.

Ai fini del rilevamento della durata, un tipo generico costruito come List<int> (in C#) o List(Of Integer) (in Visual Basic), creato e usato nella generazione di un assembly collectible, è considerato definito nell'assembly che contiene la definizione del tipo generico o in un assembly che contiene la definizione di uno dei suoi argomenti di tipo. L'assembly esatto usato è un dettaglio di implementazione e soggetto a modifiche.

Restrizioni sugli assembly collezionabili

Le seguenti restrizioni si applicano agli insiemi collezionabili.

  • Riferimenti statici

    I tipi in un assembly dinamico ordinario non possono avere riferimenti statici ai tipi definiti in un assembly collezionabile. Ad esempio, se si definisce un tipo ordinario che eredita da un tipo in un assembly raccoglibile, viene generata un'eccezione NotSupportedException. Un tipo in un assembly raccoglibile può avere riferimenti statici a un tipo in un altro assembly raccoglibile, ma questo estende la durata di vita dell'assembly di riferimento a quella dell'assembly che fa riferimento.

Le restrizioni seguenti si applicano agli assembly raccoglibili in .NET Framework:

  • Interoperabilità COM

    Nessuna interfaccia COM può essere definita all'interno di un assembly raccoglibile e nessuna istanza di tipi all'interno di un assembly raccoglibile può essere convertita in oggetti COM. Un tipo in un assembly collezionabile non può fungere da wrapper chiamabile COM (CCW) né da wrapper chiamabile in fase di runtime (RCW). Tuttavia, i tipi negli assembly raccoglibili possono usare oggetti che implementano interfacce COM.

  • Platform invoke

    I metodi con l'attributo DllImportAttribute non saranno compilati quando saranno dichiarati in un assemblaggio raccoglibile. L'istruzione OpCodes.Calli non può essere utilizzata nell'implementazione di un tipo in un assembly raccoglibile e tali tipi non possono essere distribuiti al codice non gestito. Tuttavia, è possibile richiamare il codice nativo utilizzando un punto di ingresso dichiarato in un assembly non recuperabile.

  • Marshalling

    Non è possibile eseguire il marshalling degli oggetti (in particolare i delegati) definiti negli assemblies raccoglibili. Si tratta di una restrizione per tutti i tipi transitori emessi.

  • Caricamento dell'assembly

    Reflection emit è l'unico meccanismo supportato per il caricamento di assembly raccoglibili. Gli assembly caricati attraverso qualsiasi altra modalità di caricamento degli assembly non possono essere discaricati.

  • Oggetti associati al contesto

    Le variabili statiche del contesto non sono supportate. I tipi in un assembly collezionabile non possono estendere ContextBoundObject. Tuttavia, il codice negli assembly collezionabili può usare oggetti vincolati al contesto definiti altrove.

  • Dati statici del thread

    Le variabili statiche del thread non sono supportate.

Le restrizioni seguenti si applicano agli assembly raccoglibili nelle versioni di .NET Framework e .NET precedenti a .NET 9:

  • Campi statici con FixedAddressValueTypeAttribute

    I campi statici definiti negli assembly collezionabili non possono avere l'attributo FixedAddressValueTypeAttribute applicato.

Vedere anche