Как выгрузить сборку из основного AppDomain?

Я хотел бы знать, как выгрузить сборку, загруженную в основной AppDomain.

У меня есть следующий код:

var assembly = Assembly.LoadFrom( FilePathHere );

Мне нужно/хочу иметь возможность выгружать эту сборку, когда я закончил.

Спасибо за вашу помощь.

Ответ 1

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

См. объяснение Джейсона Зандера Почему нет метода Assembly.Unload?

Если вы используете 3.5, вы можете использовать AddIn Framework, чтобы упростить управление/вызов в разных AppDomains (которые вы можете разгружать, выгружать все сборки). Если вы используете версии до этого, вам нужно создать новый appdomain, чтобы выгрузить его.

Ответ 2

Вы не можете выгрузить сборку без разгрузки всего AppDomain. Вот почему:

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

  • Скажите, что вам удалось отслеживать все дескрипторы и ссылки на уже запущенный код с помощью сборки. Предполагая, что вы не кодировали код, как только вы успешно освободили сборку, вы только освободили метаданные и IL. Код JIT'd по-прежнему распределяется в куче загрузчика домена приложения (методы JIT'd распределяются последовательно в буфере в том порядке, в котором они вызываются).

  • Последняя проблема относится к коду, который был загружен совместно, иначе формально известен как "нейтральный домен" (проверьте/поделитесь с инструментом ngen). В этом режиме генерируется код для сборки из любого домена приложения (ничего не проводного).

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

Ответ 3

Я также знаю, что это очень старый, но может помочь кому-то, у кого эта проблема! Вот один из способов, который я нашел для этого! вместо использования:

var assembly = Assembly.LoadFrom( FilePathHere );

используйте это:

var assembly = Assembly.Load( File.ReadAllBytes(FilePathHere));

Это фактически загружает "Содержимое" файла сборки, а не самого файла. Это означает, что в файле сборки нет блокировки файлов! Так что теперь он может быть скопирован, удален или обновлен без закрытия вашего приложения или попытки использовать отдельный AppDomain или Marshaling!

PROS: Очень просто исправить с помощью 1 Liner кода! CONS: Невозможно использовать AppDomain, Assembly.Location или Assembly.CodeBase.

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

assembly = null;

Ответ 4

Вы должны загрузить свои временные сборки в другой AppDomain, а когда они не используются, вы можете выгрузить этот AppDomain. Это безопасно и быстро.

Ответ 5

Если вы хотите иметь временный код, который впоследствии может быть выгружен, в зависимости от ваших потребностей класс DynamicMethod может делать то, что вы хотите. Это не дает вам классов.

Ответ 7

Я знаю его старый, но могу помочь кому-то. Вы можете загрузить файл из потока и отпустить его. Это сработало для меня. Я нашел решение ЗДЕСЬ.

Надеюсь, что это поможет.