Страницы

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

суббота, 4 января 2020 г.

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

#c_sharp


Подскажите, пожалуйста, как не держать 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);


Буду тестировать, потом отпишусь.
    


Ответы

Ответ 1



Дело в том, что методы 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(); }

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

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