内存和CPU影响时,一个DLL被嵌入一个.NET的DLL / EXE里面? [英] Memory and CPU impact when a DLL is embedded inside a .NET DLL / EXE?

查看:124
本文介绍了内存和CPU影响时,一个DLL被嵌入一个.NET的DLL / EXE里面?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我们有我们分发对其他DLL外部依赖的DLL。而不是冒着丢失的DLL或具有潜在的混合和匹配的情况下,我们嵌入的DLL我们自己的DLL / EXE里面并加载它在运行时,以满足运行时链接。

问:

A)

之间
  • 在嵌入我们的.EXE / .DLL里面的DLL,然后加载到内存在运行时 和
  • 在保持DLL的文件系统上的一个单独的文件,然后让系统加载我们

哪种方法会消耗更多的内存和大约多少钱?

B)有没有人有比上面的更好的办法?特别是对于在详细资料#3 的下面。


的兴趣在我们的程序的详细资料:

  1. 注册为AssemblyResolve事件时,我们知道运行code在装配之前调用的部分(如:初始化时间)

     公共无效SomeInit code()
    {
        ...
        AppDomain.CurrentDomain.AssemblyResolve + =(发件人,参数)=>
        {
            串[] assemblyDetail = args.Name.Split(,);
            变种的AssemblyName = assemblyDetail [0] +为.dll;
    
            变种thisAssembly = Assembly.GetExecutingAssembly();
            变种allResourceNames = thisAssembly.GetManifestResourceNames();
    
            串requiredResName = allResourceNames.SingleOrDefault(一个=> a.EndsWith(的AssemblyName));
    
            使用(VAR输入= thisAssembly.GetManifestResourceStream(requiredResName))
            {
                返回输入!= NULL
                     ?的Assembly.Load(StreamToBytes(输入))
                     : 空值;
            }
        };
        ...
    }
    
    静态的byte [] StreamToBytes(流输入)
    {
        无功容量= input.CanSeek? (int)的input.Length:0;
        使用(VAR输出=新的MemoryStream(容量))
        {
            INT读数长度;
            VAR缓冲区=新的字节[4096];
    
            做
            {
                读数长度= input.Read(缓冲液,0,buffer.Length);
                output.Write(缓冲液,0,读数长度);
            }
            而(读数长度!= 0);
    
            返回output.ToArray();
        }
    }
     

  2. 嵌入汇编。这是通过添加现有项目,以.NET项目=>挑.DLL =>确定。回去挑.dll和在性质改变建设行动,以嵌入的资源。

  3. 我们还必须添加相同的.DLL作为参考,还需要有使用ExternalNamespace;对类使用它的顶部语句。如果没有,构建过程失败,因为它无法看到外部DLL code在编译时。因此,作为一个生成后的行动,我们必须从最后的斌删除.dll文件(而不是它的嵌入式克隆)文件夹。

解决方案

答:只要将内部组件本身不具备一定规模庞大(一些大规模的嵌入式资源,例如)应该工作的可接受的 - 这是一个有点wriggly的答案,但我没有一个更好的除衡量。我(以及类似的原因)做得非常类似的事情偶尔为之。

B:将复制本地上的参考属性( F4 ),以。您需要在使用ExternalNamespace; 即使这些文件是在同一个项目 - 刚刚带来的空间发挥作用

We have a DLL we distribute that has external dependencies on other DLLs. Rather than risking missing DLLs or having potential mix-and-matching situations, we embed the DLLs inside our own DLL/EXE and load it at runtime to satisfy runtime linking.

Question:

A) Between

  • embedding the DLL inside our .EXE/.DLL and then loading it into memory at runtime and
  • keeping the DLL as a separate file on the file system and then having the system load it for us

which approach consumes more memory and by approximately how much?

B) Does anyone have a better approach than the above? Especially for item #3 in the details below.


Details on our process for the interested:

  1. Register for the AssemblyResolve event at a portion that we know runs before the code in the assembly is called (eg: init time)

    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. Embed the assembly. This is done by "Add existing item" to the .NET project => pick the .dll => ok. Go back and pick the .dll and in properties change the "Build action" to "Embedded Resource".

  3. We still have to add the same .DLL as a reference and still need to have the using ExternalNamespace; statements on the top of classes using it. If not, build process fails since it can't see the external DLL code at compile time. So as a post-build action, we have to delete the .DLL file (not it's embedded clone) from the final bin folder.

解决方案

A: as long as the inner assembly doesn't itself have some huge size (some massive embedded resource, for example) it should work acceptably - that is a bit of a wriggly answer, but I don't have a better one other than "measure it". I've done very similar things occasionally (and for similar reasons).

B: set "Copy Local" on the reference properties (f4) to False. You would need the using ExternalNamespace; even if the files were in the same project - that just brings the namespace into play.

这篇关于内存和CPU影响时,一个DLL被嵌入一个.NET的DLL / EXE里面?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆