Assembly.Load性能影响

时间:2012-09-04 10:21:37

标签: c# performance clr .net-assembly system.reflection

我正在开发一个组件,它执行使用ioc注册的任何接口的临时方法,执行时刻取决于不同的触发器。它必须能够保存要对数据库执行的操作,因此我将方法名称,类型和参数列表(序列化为BLOB)保存到数据库中,直到需要为止。

当触发发生时,我需要在类型的实例上执行方法。因为我正在使用依赖注入,所以我将接口名称保存到数据库中(格式为"Namespace.IInterface, AssemblyName"

要在ioc容器上运行Resolve<IInterface>()方法,我需要其Type的实例:

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

我的问题是:

  • 是否有更好的方法从名称中获取Type的实例if 我确定包含程序集已经加载到app域中了吗? (我只用Type.Load(typeName)尝试但是空了
  • 如果已加载有问题的程序集,CLR会优化该进程(使用已加载),还是需要手动缓存程序集列表以防止反复加载同一程序集对性能产生影响?

4 个答案:

答案 0 :(得分:5)

  • 如果您使用的typeName包含程序集名称(类似MyNamespace.MyType, MyAssembly version=1.0.0.0,publicKeyToken=12345etc),则Type.Load(typeName)将获取您的类型但不为null;
  • CLR只负责加载程序集一次(每个上下文一次,details is here,在你的情况下上下文保持不变,所以答案是你应该放松并将缓存保留到CLR :))。

答案 1 :(得分:3)

  

如果我确定包含程序集已加载到应用程序域中,是否有更好的方法从其名称获取Type实例? (我尝试使用简单的Type.Load(typeName)但是得到了null)

没有

  

如果已加载有问题的程序集,CLR将优化该程序(使用已加载)

每个程序集只加载一次。

答案 2 :(得分:2)

  

如果已加载有问题的程序集,CLR会对其进行优化   过程(使用已加载)

仅在MSDN文章step 2How the Runtime Locates Assemblies上回答此问题:

如果所请求的程序集还在之前的调用中 ,则公共语言运行时使用的程序集已加载。在命名构成应用程序的程序集时,这可能会产生分歧。有关命名程序集的详细信息,请参阅Assembly Names


与问题没有直接关系,但也很有用:

如果先前的程序集请求失败,则后续的程序集请求会立即失败,而不会尝试加载程序集。从.NET Framework 2.0版开始,缓存程序集绑定失败,缓存的信息用于确定是否尝试加载程序集。

答案 3 :(得分:0)

为了验证性能影响,我尝试加载相同的程序集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
}