C# 为什么.NET framework会锁定DLL?

C# 为什么.NET framework会锁定DLL?,c#,.net,C#,.net,既然DLL加载到内存中,那么运行进程必须锁定引用DLL有什么原因吗?除了将DLL复制到临时文件夹并从那里加载之外,还有其他方法可以绕过锁定吗?这是CLR创建程序集的内存映射视图以将其映射到内存的副作用。内存映射文件是Windows中的一种低级功能,在.NET 4.0中也通过MemoryMappedFile类公开。否则,这是Windows等按需分页虚拟内存操作系统中的常见功能 MMF具有许多理想的性能。“加载”程序集的动作变得非常简单和快速。实际上没有从文件中读取任何内容,它是以惰性方式发生的。文

既然DLL加载到内存中,那么运行进程必须锁定引用DLL有什么原因吗?除了将DLL复制到临时文件夹并从那里加载之外,还有其他方法可以绕过锁定吗?

这是CLR创建程序集的内存映射视图以将其映射到内存的副作用。内存映射文件是Windows中的一种低级功能,在.NET 4.0中也通过MemoryMappedFile类公开。否则,这是Windows等按需分页虚拟内存操作系统中的常见功能

MMF具有许多理想的性能。“加载”程序集的动作变得非常简单和快速。实际上没有从文件中读取任何内容,它是以惰性方式发生的。文件中的每个字节都有相应的内存地址。当CLR第一次尝试读取程序集元数据或IL中的字节时,处理器会触发一个页面错误,因为该页面在RAM中不可用。操作系统通过从磁盘动态读取文件内容来处理它。CLR继续运行,就好像什么也没发生一样,它完全不知道发生了什么

这种惰性访问非常好,你不用为你不用的东西付费。因此,如果您需要一个单一类型中的单一方法,比如说,一个像Microsoft.VisualBasic.dll这样的大型程序集,那么您只需为该方法付费。您的程序从未实际读取其他类型的元数据或其他方法的IL

还有更多。提交内存也不需要付费。如果机器上的另一个进程需要RAM,那么包含程序集数据的页面可以简单地丢弃。因为它们可以从文件中重新加载。它们不必由分页文件支持,分页文件是您可以买到的最便宜的虚拟内存

还有更多。程序集数据总是需要随时从文件中重新加载,这一事实也意味着允许任何人修改文件永远都是不正确的。因为这会导致RAM中的数据与文件中的数据不匹配。由于无法观察到页面错误,因此它可以从CLR的角度随机更改。因此,MMF会对文件进行硬锁定,没有人可以处理它。这是一个免费的反恶意软件功能


还有更多。锁保证还意味着CLR永远不必处理不再匹配程序集中IL的jitted代码。由于程序集中的随机更改几乎不可能与代码执行正确同步,因此实现起来非常困难。而且它会非常昂贵,方法调用不再是简单的调用指令。而且它不仅限于代码,委托对象的目标方法必须动态解析。非常重要的性能杀手。否则问题就解决了,这就是为什么CLR支持AppDomain的概念。卸载appdomain会破坏所有内容、代码和数据。卷影复制程序集背后的底层技术,如在ASP.NET之类的高可用性应用程序中使用的,可能是因为您通常不希望正在运行的代码从下面被替换掉(特别是因为它还没有被JIT编译).Windows和Windows应用程序有很强的锁定它们使用或依赖的文件的倾向。如果您发布您的问题,您可能会得到一个解决方法。@BradleyDotNET:嗯,这是很有争议的。一般来说,如果没有技术上的理由阻止某人做某事,那么通常允许不将其加载到内存中。并非所有必需的DLL部分都是按需加载的.Aaaah内存映射文件。这是有道理的。谢谢你提供的所有信息!