2013-05-29 4 views
0

im using Assembly.Load (byte []) для динамической загрузки некоторых DLL, которые пользователь добавляет при необходимости. Что произойдет, если я вызову Assembly.Load (byte []) несколько раз, будучи загруженным с этого байта []? Я спрашиваю об этом, потому что в моей программе вызов для загрузки dll выполняется каждый раз, когда это необходимо, вместо того, чтобы сохранять ссылку на него где-то. Будет ли он загружать одну и ту же DLL несколько раз? Будет ли он загружать только один раз и обновлять уже загруженный? Проверка визуального отладчика студии - это только одна копия dll, так что кажется прекрасным, но возникает другой вопрос. Я попытался изменить dll и добавить новый (с более новой версией), теперь имеющий оба файла dll, старый и новый, и im, вызывающий Assembly.Load (byte []) для обоих из них (старый и новый), один за другим, вот так: загрузите старую dll, используйте ее, загрузите новую dll, используйте ее. Они отлично работают, как старые, так и новые, но только один из них загружен, так что это заставляет меня думать, что второй груз перезаписывает старый, как это работает? Есть ли у меня риск? Что происходит, если несколько пользователей загружают их? (например, веб-приложение, использующее метод, который загружает и использует обе библиотеки dll)C# Reflection, assembly.load byte []

ответ

2

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

Что произойдет, если я вызову Assembly.Load (byte []) несколько раз, будучи байтом [] загруженным с того же времени?

Он будет загружать новую сборку каждый раз, когда вы вызываете Assembly.Load(byte[]), независимо от того, используете ли вы один байт или читаете его из файла каждый раз.

Вы можете проверить это сами:

// WhoCares.exe is the name of this program 
var bytes = File.ReadAllBytes(@"WhoCares.exe"); 

var asm1 = Assembly.Load(bytes); 
var asm2 = Assembly.Load(bytes); 
var asm3 = Assembly.Load(bytes); 

var domainAssemblies = AppDomain.CurrentDomain.GetAssemblies(); 

foreach (var asm in domainAssemblies) 
{ 
    Console.WriteLine(asm.FullName); 
} 

И вывод:

 
mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 
WhoCares, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null 
WhoCares, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null 
WhoCares, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null 
WhoCares, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null 
Press any key to continue . . . 

Есть ли им риск иметь?

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

+0

Это интересно, но почему я вижу только 1 сборку, загруженную в «модули» из отладчика ?. – user1777914

+0

Ну, вы были правы, сборщики загружались много раз. Теперь я попытаюсь загрузить их в AppDomain, проблема в том, какое имя я ему даю? Нужно ли быть уникальным? Что происходит, когда происходит несколько одновременных вызовов метода, и все они пытаются создать домен приложения и загрузить сборку? – user1777914

+0

Спасибо. Я создал объект AssemblyLoader, который использует словарь , где string является именем файла + файла, как длинным приложением к нему. Если сборка уже загружена, она не загружает ее снова и возвращает уже загруженную сборку. https://github.com/rhyous/SimplePluginLoader/blob/master/Rhyous.SimplePluginLoader/AssemblyLoader.cs – Rhyous

Смежные вопросы