Страницы

Поиск по вопросам

понедельник, 28 января 2019 г.

Как отпустить длл, чтобы её можно было заменить?(Assembly,Methodinfo,invoke)

Подскажите, пожалуйста, как не держать dll, после использования следующей конструкции:
Assembly a = Assembly.LoadFile(dll); Type t = a.GetTypes().FirstOrDefault(x => x.Name == "MainDllClass"); MethodInfo mi = t.GetMethod("WorkTimer"); mi.Invoke(null, arguments);
Вызывается метод WorkTimer из класса MainDllClass файла dll. Почему-то после отработки, он продолжает использоваться и не дает перезаписать файл dll
хм кажется получается вот так:
AppDomain dom = AppDomain.CreateDomain("some"); AssemblyName assemblyName = new AssemblyName(); assemblyName.CodeBase = pathToAssembly; Assembly a = dom.Load(assemblyName); Type t = a.GetTypes().FirstOrDefault(x => x.Name == "MainDllClass"); MethodInfo mi = t.GetMethod("WorkTimer"); mi.Invoke(null, arguments); AppDomain.Unload(dom);
Буду тестировать, потом отпишусь.


Ответ

Дело в том, что методы Assembly.Load(), Assembly.LoadFrom(), Assembly.LoadFile() загружают сборку в текущий домен приложения на постоянной основе. Эта загрузка блокирует файлы сборок. Единственный способ выгрузить сборку - выгрузка целого домена приложения. Существует прием, позволяющий избежать блокирования сборок, который называется теневым копированием: MSDN. Теневое копирование сборок

Если выгрузка библиотеки вам не требуется, а требуется лишь чтобы библиотеку можно выло безболезненно удалить/заменить при работающем экземпляре приложения (например, обновление ASP.NET приложения), то можно использовать перегруженную версию Assembly.Load() принимающую "образ" библиотеки в виде массива байтов, например:
Библиотека:
namespace TestLib { public class Summator { public int Sum(int x, int y) => x + y; } }
Использование:
static void Main(string[] args) { var raw = File.ReadAllBytes(@"Путь\До\Файла\TestLib.dll"); var assembly = Assembly.Load(raw); Type type = assembly.GetTypes().First(x => x.Name == "Summator"); var instance = Activator.CreateInstance(type); MethodInfo mInfo = type.GetMethod("Sum"); var res = (int)mInfo.Invoke(instance, new object[] { 10, 15 }); Console.WriteLine(res); Console.ReadLine(); }

Комментариев нет:

Отправить комментарий