【问题标题】:Load dll in .net without locking it在.net中加载dll而不锁定它
【发布时间】:2013-09-21 17:52:38
【问题描述】:

我正在执行一项任务,我必须加载 dll 并从中获取一些信息,例如类名等...但是当我将该 dll 加载到我的代码中时,它会被锁定并且无法构建源代码,直到我关闭加载程序,我已经尝试了某些解决方案,但它们都不适合我

  1. Shadowcopy:在这种情况下,当我进行卷影复制程序集时,之后如果我更改了某些内容
    我的主 dll 在我的加载应用程序中仍然是旧的。

  2. System.Reflection.assembly.loadfrom(System.IO.GetBytes("asm-path")); //有时工作,但并非总是工作

  3. System.Reflection.assembly.ReflectionOnlyConext(); //不起作用

有没有合适的解决办法

【问题讨论】:

  • Assembly.LoadFrom() 没有采用 byte[] 的重载,而且 System.IO 中当然没有名为 GetBytes() 的方法。相当草率的研究。 Assembly.Load(byte[]) 肯定不能对文件加锁。不要使用它。

标签: c# .net dll


【解决方案1】:

一种方法是读取文件的字节并使用 Assembly.Load 的重载,它接收一个字节数组,类似于您在第二个示例中所做的。我不确定System.IO.GetBytes 是什么,但请尝试使用File.ReadAllBytes

byte[] assemblyBytes = File.ReadAllBytes("asm-path");
var assembly = Assembly.Load(assemblyBytes);

但是,这可能还不够,具体取决于您要执行的操作,因为您无法在加载程序集后将其卸载。要解决此问题,如果需要,可以将程序集加载到它自己的 AppDomain 中,然后在完成后卸载 AppDomain。

AppDomain ad = AppDomain.CreateDomain("New_Assembly_AD");
byte[] assemblyBytes = File.ReadAllBytes("asm-path");
var assembly = ad.Load(assemblyBytes);  

完成assembly 对象后,您可以卸载AppDomain。

AppDomain.Unload(ad);

【讨论】:

  • AppDomains with shadow-copy 是您正确完成此任务的唯一方法。
  • 新的 appdomain 是唯一理智的方法...请注意,反射也必须在新的 AppDomain 中进行,以避免将类型泄漏到原始域中(这也会将程序集加载到原始域中,所有的努力都被浪费了)。
  • @AlexeiLevenkov - 很好的电话,明确提到工作应该在新的 AppDomain 中完成,谢谢。
  • @AlexeiLevenkov 请提供一些代码示例 [注意,也必须在新的 AppDomain 中进行反射以避免将类型泄漏到原始域中]
【解决方案2】:

也许只是在您检查信息后尝试发布文件? 这样它可能只会被锁定几毫秒。

如果这不起作用。复制dll并使用副本...

如果您想在 dll 更改时刷新信息,您可以编写一个目录侦听器,并在原始 dll 更新时执行一些操作。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-09-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-04-21
    相关资源
    最近更新 更多