Собираемые сборки для динамической генерации типа
Собираемые сборки являются динамическими, их можно выгрузить, не выгружая домен приложения, в котором они были созданы. Вся управляемая и неуправляемая память, используемая собираемой сборкой и содержащими ее типами, может быть восстановлена. Такая информация, как имя сборки, удаляется из внутренних таблиц.
Чтобы включить выгрузку, при создании динамической сборки используйте флаг AssemblyBuilderAccess.RunAndCollect. Сборка является временной (несохраняемой) и имеет ограничения, указанные в разделе Ограничения собираемых сборок. Среда CLR автоматически выгружает собираемую сборку после освобождения всех связанных с ней объектов. Во всех других отношениях собираемые сборки создаются и используются аналогично другим динамическим сборкам.
Время существования собираемых сборок
Время существования собираемой динамической сборки зависит от наличия ссылок на содержащиеся в ней типы и на объекты, создаваемые из таких типов. Среда CLR не выгружает сборку, пока существует хотя бы один из следующих экземпляров (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> (List(Of Integer) в Visual Basic), создаваемый и используемый при генерации собираемой сборки, считается определенным либо в сборке с определением универсального типа, либо в сборке с определением одного из ее аргументов типа. Используемая сборка является деталью реализации и подлежит изменению.
Ограничения собираемых сборок
К собираемым сборкам применяются следующие ограничения.
Статическая ссылка Типы в обычной динамической сборке не могут иметь статические ссылки на типы, определенные в собираемой сборке. Например, если определяется обычный тип, наследующий тип из собираемой сборки, выдается исключение NotSupportedException. Тип в собираемой сборке может иметь статические ссылки на тип в другой собираемой сборке, однако при этом увеличивается время существования сборки, на которую указывает ссылка, до времени существования сборки, из которой указывает ссылка.
COM-взаимодействие В собираемой сборке невозможно определить COM-интерфейсы, а экземпляры типов в собираемой сборке невозможно преобразовать в COM-объекты. Тип в собираемой сборке не может служить в качестве вызываемой оболочки COM или вызываемой оболочки времени выполнения. Однако типы в собираемых сборках могут использовать объекты, реализующие COM-интерфейсы.
Вызов неуправляемого кода Методы с атрибутом DllImportAttribute не будут выполнять компиляцию, если они объявляются в собираемой сборке. При реализации типа в собираемой сборке нельзя использовать инструкцию OpCodes.Calli, и такие типы невозможно маршалировать в неуправляемый код. Однако их можно вызвать в машинный код с помощью точки входа, объявленной в несобираемой сборке.
Маршалинг Маршалировать объекты, определенные в собираемых сборках (в частности, делегаты) невозможно. Это ограничение для всех временных выдаваемых типов.
Загрузка сборки Порождение отражения является единственным механизмом, поддерживаемым для загрузки собираемых сборок. Сборки, загружаемые любым другим способом загрузки сборок, невозможно выгрузить.
Контекстно-привязанные объекты Контекстно-статические переменные не поддерживаются. Типы в собираемой сборке не могут расширять ContextBoundObject. Однако код в собираемых сборках может использовать контекстно-привязанные объекты, определенные в другой части кода.
Потокостатические данные Потокостатические переменные не поддерживаются.