Сборка. Влияние нагрузки на производительность

Я работаю над компонентом, который выполняет предварительный метод любого интерфейса, зарегистрированного в ioc, и момент выполнения зависит от разных триггеров. Он должен иметь возможность сохранять действия, которые необходимо выполнить, в базе данных, поэтому я сохраняю имя метода, тип и список параметров (сериализованных в BLOB) в базу данных до тех пор, пока они не понадобятся.

Когда возникает триггер, мне нужно выполнить метод для экземпляра типа. Поскольку я использую внедрение зависимостей, у меня есть имя интерфейса, сохраненное в базе данных (в формате "Namespace.IInterface, AssemblyName")

Чтобы запустить метод Resolve<IInterface>() в контейнере ioc, мне нужен экземпляр его Type:

Assembly assembly = System.Reflection.Assembly.Load(assemblyName);
Type service = assembly.GetType(typeName);
object instance = IOCContainer.Resolve(service);

Мои вопросы:

  • Есть ли лучший способ получить экземпляр Type по его имени, если я уверен, что содержащая его сборка уже загружена в домен приложения? (я пытался использовать просто Type.Load(typeName), но получил null)
  • Если рассматриваемая сборка уже загружена, будет ли CLR оптимизировать этот процесс (использовать уже загруженные) или мне нужно вручную кэшировать список сборок, чтобы предотвратить влияние на производительность многократной загрузки одной и той же сборки снова и снова?

person Goran Obradovic    schedule 04.09.2012    source источник


Ответы (4)


  • Если typeName, который вы используете, включает имя сборки (что-то вроде MyNamespace.MyType, MyAssembly version=1.0.0.0,publicKeyToken=12345etc), то Type.Load(typeName) получит ваш тип, но не null;
  • CLR загружает сборку только один раз (один раз для каждого контекста, подробности здесь, в вашем случае контекст остается прежним, поэтому ответ заключается в том, что вам следует расслабиться и оставить кэширование CLR :)).
person alex.b    schedule 04.09.2012
comment
спасибо за ссылку на лучшие практики, это должно быть под см. также в Assembly.Load Method ( Строка) - person Goran Obradovic; 04.09.2012

Есть ли лучший способ получить экземпляр Type по его имени, если я уверен, что содержащая его сборка уже загружена в домен приложения? (Я пробовал просто Type.Load(typeName), но получил null)

No.

Если рассматриваемая сборка уже загружена, будет ли CLR оптимизировать этот процесс (использовать уже загруженную)

Да.

Каждая сборка загружается только один раз.

person Serg Rogovtsev    schedule 04.09.2012

Если рассматриваемая сборка уже загружена, будет ли CLR оптимизировать этот процесс (использовать уже загруженную)

Ответ только на этот вопрос находится на шаге 2 статьи MSDN Как среда выполнения находит сборки:

Если запрошенная сборка также запрашивалась в предыдущих вызовах, общеязыковая среда выполнения использует уже загруженную сборку . Это может иметь последствия при именовании сборок, составляющих приложение. Дополнительные сведения об именовании сборок см. в разделе Имена сборок.


Не имеет прямого отношения к вопросу, но тоже полезно:

Если предыдущий запрос на сборку завершился неудачно, последующие запросы на сборку завершатся сбоем немедленно, без попытки загрузить сборку. Начиная с .NET Framework версии 2.0, ошибки привязки сборки кэшируются, и кэшированная информация используется для определения того, следует ли пытаться загрузить сборку.

person Goran Obradovic    schedule 04.09.2012

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

Чтобы попробовать сделать следующее:

while (true)
{
    Assembly assembly = Assembly.LoadFrom("abc.dll");
    //monitor: AppDomain.CurrentDomain.MonitoringTotalAllocatedMemorySize
    //memory growing with each call
}

=============

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

var typeName = "Namespace.ClassName, Namespace";

while (true)
{
   var typeFound = Type.GetType(typeName);
   if (typeName == null)
   {
       Assembly assembly = Assembly.LoadFrom("abc.dll");
   }
   //monitor: AppDomain.CurrentDomain.MonitoringTotalAllocatedMemorySize
   //memory will not grow after first call
}
person Muhammad Amir    schedule 10.01.2017