Поделиться через


Забираемые сборки для динамической генерации типа

Забираемые сборки — это динамические сборки, которые можно выгрузить без выгрузки домена приложения, в котором они были созданы. Всю управляемую и неуправляемую память, используемую забираемой сборкой и содержащимися в ней типами, можно освободить. Сведения, такие как имя сборки, удаляются из внутренних таблиц.

Чтобы включить выгрузку, используйте флаг AssemblyBuilderAccess.RunAndCollect при создании динамической сборки. Сборка является временной (т. е. не может быть сохранена) и подлежит ограничениям, описанным в разделе "Ограничения на сборные сборки ". Общеязыковая среда выполнения (CLR) автоматически выгружает забираемую сборку, когда вы освободите все связанные со сборкой объекты. Во всех прочих отношениях забираемые сборки создаются и используются так же, как и другие динамические сборки.

Время существования забираемых сборок

Время существования забираемой сборки определяется наличием ссылок на содержащиеся в ней типы и объекты, созданные из этих типов. Общеязыковая среда выполнения не выгружает сборку, пока существует хотя бы один из следующих элементов (T — любой тип, определенный в сборке):

  • Экземпляр T.

  • Экземпляр массива T.

  • Экземпляр универсального типа, имеющий T в качестве одного из аргументов типа. Сюда входят универсальные коллекции T, даже если такая коллекция пуста.

  • Экземпляр Type или TypeBuilder, представляющий T.

    Внимание

    Нужно освободить все объекты, представляющие части сборки. ModuleBuilder, определяющий T, хранит ссылку на TypeBuilder, а объект AssemblyBuilder хранит ссылку на ModuleBuilder, поэтому ссылки на эти объекты нужно освободить. Даже наличие LocalBuilder или ILGenerator, используемых при создании T, препятствует выгрузке.

  • Статическая ссылка на T со стороны другого динамически определяемого типа T1, который все еще доступен выполняющемуся коду. Например, T1 может наследовать от T или T может быть типом параметра в методе T1.

  • Значение ByRef для статического поля, к Tкоторому принадлежит.

  • RuntimeTypeHandle, RuntimeFieldHandle или RuntimeMethodHandle, ссылающийся на T или на компонент T.

  • Экземпляр любого объекта отражения, который можно использовать косвенно или напрямую для обращения к объекту Type, представляющему T. Например, объект Type для T можно получить из типа массива с типом элементов T или из универсального типа, имеющего аргумент типа T.

  • Метод M в стеке вызовов любого потока, где M — это метод T или метод уровня модуля, который определен в сборке.

  • Делегат статического метода, определенного в модуле сборки.

Если всего один элемент из этого списка существует только для одного типа или метода в сборке, среда выполнения не может выгрузить сборку.

Примечание.

Среда выполнения не выгружает сборку, пока не выполнены методы завершения для всех элементов в списке.

В целях отслеживания времени существования, созданный универсальный тип, например List<int> (в C#) или List(Of Integer) (в Visual Basic), созданный и используемый в создании сборочной сборки, считается определенным в сборке, содержащей определение универсального типа или в сборке, содержащей определение одного из его аргументов типа. Точная сборка, используемая, является подробной реализацией и подлежит изменению.

Ограничения забираемых сборок

К забираемым сборкам применяются следующие ограничения:

  • Статические ссылки

    Типы в обычной динамической сборке не могут иметь статические ссылки на типы, определенные в забираемой сборке. Например, если вы определяете обычный тип, наследующий от типа в забираемой сборке, возникает исключение NotSupportedException. Тип в забираемой сборке может иметь статические ссылки на тип в другой забираемой сборке, но при этом время существования сборки, на которую указывает ссылка, становится равным времени существования сборки с такой ссылкой.

Следующие ограничения применяются к сборным сборкам в платформа .NET Framework:

  • COM-взаимодействие

    COM-интерфейсы не могут быть заданы внутри забираемой сборки, и никакие экземпляры типов в забираемой сборке не могут быть преобразованы в COM-объекты. Тип в забираемой сборке не может служить в качестве вызываемой оболочки COM (CCW) или вызываемой оболочки времени выполнения (RCW). Однако типы в забираемых сборках могут использовать объекты, реализующие COM-интерфейсы.

  • Вызов неуправляемого кода

    Методы, имеющие атрибут, DllImportAttribute не компилируются при объявлении в сборной сборке. Инструкцию OpCodes.Calli нельзя использовать в реализации типа в сборочной сборке, и такие типы нельзя маршаллировать в неуправляемый код. Однако можно вызвать машинный код с помощью точки входа, объявленной в сборке, отличной от сбора.

  • Маршалинг

    Объекты (в частности, делегаты), определенные в сборных сборках, нельзя маршалировать. Это ограничение действует для всех временных выдаваемых типов.

  • Загрузка сборок

    Рефлексия выдается единственный механизм, поддерживаемый для загрузки сборочных сборок. Сборки, загружаемые любым другим образом, выгрузить невозможно.

  • Контекстно привязанные объекты

    Контекстно статические переменные не поддерживаются. Типы в забираемой сборке не могут расширять ContextBoundObject. Однако код в забираемых сборках может использовать контекстно привязанные объекты, определенные в другом месте.

  • Потокостатические данные

    Не поддерживаются статические переменные потока.

Следующие ограничения применяются к сборным сборкам в платформа .NET Framework и версиях .NET до .NET 9:

  • Статические поля с FixedAddressValueTypeAttribute

    Статические поля, определенные в сборных сборках, не могут FixedAddressValueTypeAttribute применять атрибут.

См. также