内存和CPU影响时,一个DLL被嵌入一个.NET的DLL / EXE里面?里面、内存、CPU、DLL

2023-09-04 13:24:27 作者:Donahue 唐纳修

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

问:的

A)

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

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

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

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

注册为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();
    }
}
 

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

升级win10后CPU或内存占用大是什么原因

我们还必须添加相同的.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:

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();
    }
}

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".

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.