Partilhar via


Montagens colecionáveis para geração de tipo dinâmico

Assemblies colecionáveis são assemblies dinâmicos que podem ser descarregados sem descarregar o domínio de aplicação em que foram criados. Toda a memória gerenciada e não gerenciada usada por um assembly colecionável e os tipos que ele contém podem ser recuperados. Informações como o nome do conjunto (assembly) são removidas das tabelas internas.

Para habilitar o descarregamento, use o AssemblyBuilderAccess.RunAndCollect sinalizador ao criar um assembly dinâmico. A assembly é transitória (ou seja, não pode ser guardada) e está sujeita a limitações que são descritas na seção Restrições sobre assemblies colecionáveis. O Common Language Runtime (CLR) descarrega um assembly colecionável automaticamente quando você libera todos os objetos associados ao assembly. Em todos os outros aspetos, os conjuntos colecionáveis são criados e usados da mesma forma que outros conjuntos dinâmicos.

Vida útil dos conjuntos colecionáveis

O tempo de vida de um assembly colecionável é controlado pela existência de referências aos tipos que ele contém e aos objetos que são criados a partir desses tipos. O common language runtime não descarrega um assembly desde que exista um ou mais dos seguintes itens (T é qualquer tipo definido no assembly):

  • Um exemplo de T.

  • Uma instância de uma matriz de T.

  • Uma instância de um tipo genérico que tem T como um de seus argumentos de tipo. Isso inclui coleções genéricas de T, mesmo que essa coleção esteja vazia.

  • Uma instância de Type ou TypeBuilder que representa T.

    Importante

    Você deve liberar todos os objetos que representam partes da montagem. O ModuleBuilder que define T mantém uma referência ao TypeBuilder, e o AssemblyBuilder objeto mantém uma referência ao ModuleBuilder, portanto, as referências a esses objetos devem ser liberadas. Mesmo a existência de um LocalBuilder ou um ILGenerator usado na construção de T impede a descarga.

  • Uma referência estática a T por outro tipo T1 definido dinamicamente que ainda pode ser alcançado pela execução de código. Por exemplo, T1 pode derivar de T, ou T pode ser o tipo de um parâmetro em um método de T1.

  • A ByRef a um campo estático que pertence a T.

  • A RuntimeTypeHandle, RuntimeFieldHandle, ou RuntimeMethodHandle que se refere a T ou a um componente de T.

  • Uma instância de qualquer objeto de reflexão que possa ser usado indiretamente ou diretamente para acessar o objeto Type que representa T. Por exemplo, o Type objeto para T pode ser obtido de um tipo de matriz cujo tipo de elemento é T, ou de um tipo genérico que tem T como argumento de tipo.

  • Um método M na pilha de chamadas de qualquer thread, onde M é um método de T ou um método a nível de módulo que está definido no assembly.

  • Um delegado para um método estático definido em um módulo do assembly.

Se apenas um item desta lista existir para apenas um tipo ou um método no assembly, a execução não poderá descarregar o assembly.

Observação

Na verdade, o tempo de execução não descarrega a assemblagem até que os finalizadores tenham sido executados para todos os itens da lista.

Para fins de controle do tempo de vida, um tipo genérico construído como List<int> (em C#) ou List(Of Integer) (em Visual Basic) que é criado e usado na geração de um assembly colecionável é considerado como tendo sido definido no assembly que contém a definição de tipo genérico ou em um assembly que contém a definição de um de seus argumentos de tipo. A montagem exata usada é um detalhe de implementação e encontra-se sujeita a alterações.

Restrições a montagens colecionáveis

As seguintes restrições se aplicam a montagens colecionáveis:

  • Referências estáticas

    Os tipos em um assembly dinâmico ordinário não podem ter referências estáticas a tipos definidos em um assembly colecionável. Por exemplo, se você definir um tipo comum que herda de um tipo em um assembly colecionável, uma NotSupportedException exceção será lançada. Um tipo em um assembly colecionável pode ter referências estáticas a um tipo em outro assembly colecionável, mas isso prolonga o tempo de vida do assembly referenciado para corresponder ao tempo de vida do assembly que faz a referência.

As seguintes restrições se aplicam a assemblies colecionáveis no .NET Framework:

  • Interoperabilidade COM

    Nenhuma interface COM pode ser definida dentro de um assembly colecionável e nenhuma instância de tipos dentro de um assembly colecionável pode ser convertida em objetos COM. Um tipo em um assembly colecionável não pode servir como um COM callable wrapper (CCW) ou um runtime callable wrapper (RCW). No entanto, os tipos em assemblies colecionáveis podem usar objetos que implementam interfaces COM.

  • Platform Invoke

    Os métodos que têm o atributo DllImportAttribute não serão compilados quando forem declarados numa assembly colecionável. A instrução OpCodes.Calli não pode ser usada na implementação de um tipo em um assembly recolhível, e esses tipos não podem ser passados para código não gerenciado. No entanto, você pode chamar o código nativo usando um ponto de entrada declarado em um assembly não colecionável.

  • Marshaling

    Os objetos (em particular, delegados) que são definidos em assemblies colecionáveis não podem ser empacotados. Esta é uma restrição para todos os tipos de emissões transitórias.

  • Carregamento da montagem

    O mecanismo de emissão de reflexão é o único suportado para carregar assemblies colecionáveis. Os assemblies que são carregados usando qualquer outra forma de carregamento de assemblagens não podem ser descarregados.

  • Objetos ligados ao contexto

    Não há suporte para variáveis estáticas de contexto. Os tipos em um conjunto colecionável não podem se estender ContextBoundObject. No entanto, o código em assemblies colecionáveis pode usar objetos ligados ao contexto que são definidos em outro lugar.

  • Dados estáticos de thread

    Não há suporte para variáveis estáticas de thread.

As restrições a seguir se aplicam a assemblies colecionáveis nas versões .NET Framework e .NET anteriores ao .NET 9:

  • Campos estáticos com FixedAddressValueTypeAttribute

    Os campos estáticos definidos em assemblies colecionáveis não podem ter o FixedAddressValueTypeAttribute atributo aplicado.

Ver também