Как выгрузить сборку из основного 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
может делать то, что вы хотите. Это не дает вам классов.
Ответ 6
Вот хороший пример, как компилировать и запускать dll во время выполнения, а затем выгружать все ресурсы:
http://www.west-wind.com/presentations/dynamicCode/DynamicCode.htm
Ответ 7
Я знаю его старый, но могу помочь кому-то. Вы можете загрузить файл из потока и отпустить его. Это сработало для меня. Я нашел решение ЗДЕСЬ.
Надеюсь, что это поможет.