简体   繁体   English

动态程序集加载,内存问题

[英]Dynamic assembly loading, memory issue

I'll mostly probably need to load the same assembly dynamically multiple times. 我通常可能需要多次动态加载同一程序集。 My questions are: 我的问题是:

  1. Will the assembly be actually loaded only once or multiple times? 程序集实际上只加载一次还是多次? The assembly itself being a DLL suggests the first option, but who knows :) 程序集本身是DLL,建议使用第一种方法,但谁知道:)
  2. I had an experience, that the same types instantiated from the same assembly, but loaded dynamically from two different places were incompatible. 我的经验是,从相同的程序集实例化相同的类型,但是从两个不同的位置动态加载是不兼容的。 Is this also the case with loading this assembly twice from the same place? 从同一位置两次加载该装配体也是如此吗?

It depends on the loading context of the assembly load. 它取决于程序集加载的加载上下文 That's a hundred dollar word that's hard to explain in an SO answer, Suzanne Cook's blog goes into the concept in detail. 这是一个一百美元的单词,很难在一个SO答案中解释,Suzanne Cook的博客详细介绍了这个概念。 In a nutshell, the context permits the CLR to figure out whether an assembly was loaded before and where it should look for dependent assemblies. 简而言之,上下文使CLR能够确定某个程序集是否在之前加载,以及在何处查找相关程序集。

It is easier to explain what can go wrong. 更容易解释可能出问题的地方。 Both Assembly.LoadFile() and Assembly.Load(byte[]) loads assemblies without a context. Assembly.LoadFile()Assembly.Load(byte[])加载没有上下文的程序集。 With the quirk that this allows an assembly to be loaded more than once since the CLR cannot determine if the assembly that's getting loaded by them was previously loaded. 奇怪的是,这允许程序集被多次加载,因为CLR无法确定由它们加载的程序集是否先前已加载。 For LoadFile() this is intentional , in very select cases you want to allow to load an assembly again. 对于LoadFile()而言,这是有意的 ,在某些特定情况下,您希望允许再次加载程序集。 For Load(byte[]) it is in inevitable accident, the CLR doesn't know enough about the identity of the assembly since it cannot know its display name. 对于Load(byte []),这是不可避免的事故,由于CLR无法知道程序集的显示名称,因此它对程序集的身份了解不够。

This is almost always bad , types in .NET have an identity that isn't just the namespace name + type name, it also includes the assembly that the type was loaded from. 这几乎总是很糟糕 ,.NET中的类型不仅具有名称空间名称+类型名称的身份,还包括从中加载该类型的程序集。 You tend to get hard to diagnose InvalidCastExceptions that read like "Unable to cast object of type Foo.Bar to type Foo.Bar". 您往往难以诊断InvalidCastException,其内容类似于“无法将类型为Foo.Bar的对象转换为类型为Foo.Bar的对象”。 That leads to clumps of head hair being lost on trying to figure out what that means and what causes it. 这导致在试图弄清这是什么意思和原因的过程中会丢失大量的头发。

Watch out for Assembly.LoadFile(), its name is entirely too innocent looking and it very rarely does what you want it to do. 提防Assembly.LoadFile(),它的名称看起来太单纯了,很少执行您想要的操作。 Use LoadFrom() instead. 使用LoadFrom()代替。 Load(byte[]) is similarly dangerous and a very poor substitute for a proper installer. 同样,Load(byte [])也很危险,并且不能很好地代替适当的安装程序。

You can't load the same assembly multiple times into the same application domain, and unless the assembly has changed it wouldn't make a lot of sense to, either. 您不能将相同的程序集多次加载到相同的应用程序域中,并且除非程序集已更改,否则也没有太大意义。

If you do want to repeatidly load an assembly then you need to load it into a different appdomain and then unload the appdomain in order to unload the assembly. 如果确实要重复加载程序集,则需要将其加载到其他appdomain中,然后卸载该appdomain以便卸载该程序集。 The reason for this is there is no explicit way to unload an assembly, only an appdomain. 这样做的原因是没有明确的方法可以卸载程序集,只有一个appdomain即可。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM