【问题标题】:Memory and CPU impact when a DLL is embedded inside a .NET DLL / EXE?将 DLL 嵌入到 .NET DLL / EXE 中时内存和 CPU 的影响?
【发布时间】:2013-04-05 00:07:19
【问题描述】:

我们有一个我们分发的 DLL,它对其他 DLL 具有外部依赖性。我们没有冒险丢失 DLL 或存在潜在的混合和匹配情况,而是将 DLL 嵌入到我们自己的 DLL/EXE 中并在运行时加载它以满足运行时链接。

问题:

A) 之间

  • 将 DLL 嵌入到我们的 .EXE/.DLL 中,然后在运行时将其加载到内存中 和
  • 将 DLL 作为一个单独的文件保存在文件系统上,然后让系统为我们加载它

哪种方法会消耗更多内存,大约消耗多少?

B) 有没有人有比上述更好的方法?特别是对于下面详细信息中的第 3 项。


有兴趣的可以详细了解一下我们的流程:

  1. 在我们知道在调用程序集中的代码之前运行的部分注册 AssemblyResolve 事件(例如:初始化时间)

    public void SomeInitCode()
    {
        ...
        AppDomain.CurrentDomain.AssemblyResolve += (sender, args) =>
        {
            string[] assemblyDetail = args.Name.Split(',');
            var assemblyName= assemblyDetail[0] + ".dll";
    
            var thisAssembly = Assembly.GetExecutingAssembly();
            var allResourceNames = thisAssembly.GetManifestResourceNames();
    
            string requiredResName = allResourceNames.SingleOrDefault(a => a.EndsWith(assemblyName));
    
            using (var input = thisAssembly.GetManifestResourceStream(requiredResName))
            {
                return input != null
                     ? Assembly.Load(StreamToBytes(input))
                     : null;
            }
        };
        ...
    }
    
    static byte[] StreamToBytes(Stream input)
    {
        var capacity = input.CanSeek ? (int)input.Length : 0;
        using (var output = new MemoryStream(capacity))
        {
            int readLength;
            var buffer = new byte[4096];
    
            do
            {
                readLength = input.Read(buffer, 0, buffer.Length);
                output.Write(buffer, 0, readLength);
            }
            while (readLength != 0);
    
            return output.ToArray();
        }
    }
    
  2. 嵌入程序集。这是通过“添加现有项目”到 .NET 项目 => 选择 .dll => 好的来完成的。返回并选择 .dll 并在属性中将“构建操作”更改为“嵌入式资源”。

  3. 我们仍然需要添加相同的 .DLL 作为引用,并且仍然需要在使用它的类的顶部有 using ExternalNamespace; 语句。如果没有,构建过程将失败,因为它在编译时看不到外部 DLL 代码。因此,作为构建后操作,我们必须从最终的 bin 文件夹中删除 .DLL 文件(不是嵌入的克隆)。

【问题讨论】:

  • 匿名close投票者:至少说出来。
  • 你不能让你的安装程序处理依赖关系?
  • 好点,但是,这是一个面向开发人员的独立免安装发行版
  • 我只想把所有东西都合并在一起 :)
  • @leppie 您应该将其添加为答案 - 这可能是一个理想的解决方案

标签: .net performance dll


【解决方案1】:

按照 Marc 的建议。

我只会使用 ILMerge 将所有内容放在一起。

这可能是不可能的,但应该适用于“纯”托管程序集(包括使用 unsafe 的程序集)。

【讨论】:

    【解决方案2】:

    答:只要内部组件本身没有太大的尺寸(例如,一些大型嵌入式资源),它应该可以可以接受 - 这是一个有点扭曲的答案,但是除了“测量它”之外,我没有更好的方法。我偶尔会做非常类似的事情(并且出于类似的原因)。

    B:将引用属性 (f4) 上的“复制本地”设置为 False。即使文件在同一个项目中,您也需要 using ExternalNamespace; - 这只是让命名空间发挥作用。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-02-03
      • 2011-10-18
      • 2021-03-15
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多