如何预加载 .net 程序集

4
在我的工作中,我们正在使用.NET Framework 4开发不同的应用程序。所有应用程序都使用我们开发的公共程序集,例如data.dll中的数据层。这些应用程序驻留在网络驱动器上,并直接从那里启动。
大多数大型应用程序需要一段时间才能启动,例如4-5秒钟(冷启动)。随后的启动速度更快,几乎是瞬间完成的。我认为这与网络无关,因为最大的程序集约为900KB,而我们正在使用千兆网络。
我想创建一个服务,该服务在计算机启动时启动,并加载特定目录下的所有.NET程序集。我希望当用户启动程序时,所有必要的程序集已经被加载和“JITed”,因此启动速度应该更快。
我知道如何创建服务,但我想知道这是否可行,因为我对CLR的理解非常有限...此外,像Assembly.LoadFrom(fileName)这样的操作是否可以预加载程序集?如果我一段时间内没有启动任何程序,它们会保持加载状态还是在一段时间后卸载?如果我更改已加载的程序集会发生什么?
基本上,我想做类似于OpenOffice Quick starter的东西,但是针对我们自己的应用程序框架。
谢谢大家!!!
---编辑--- 这很有趣...似乎朝着正确的方向前进,但不确定我是否理解了一切...

可能是预加载程序集的重复问题。 - Robert Harvey
我搜索了但没有找到那篇文章...不管怎样,这并不是完全相同的情况。他试图在应用程序“空闲时间”预加载程序集,而我想从另一个应用程序中加载它们。 - Pierre-Olivier Goulet
4个回答

2
你已经知道JIT编译不是问题,因为这也会减慢第二次启动。你需要做的就是将DLL文件放入文件系统缓存中。这样,当您稍后启动程序时,它将使用来自缓存的该DLL副本,而不是在网络附加驱动器中查找它,这需要时间。Office快速启动也使用了同样的技巧。如果所有这些预加载的内容都不再适合,就不知道谁会获胜了。
只需创建一个Winforms应用程序,这样您就不会得到窗口,并调用Assembly.Load()来获取已加载的程序集,File.ReadAllBytes()以确保整个内容都在缓存中。将该程序的快捷方式放入启动文件夹中。您提到的那个程序集足够大,可以从Ngen.exe中获得热启动的提升。但必须在每个工作站上运行它。

1

您可以使用以下文章中描述的技术以编程方式预先 JIT 组件:在运行时预编译(pre-JIT)程序集,或提前触发 JIT 编译。

但是,我不认为在一个进程中 JIT 它们会对另一个进程产生影响(不确定)。一种可能的解决方案是在计算机上启动应用程序,并使用命令行选项指示它仅预先 JIT 组件并且不执行其他任何操作。当用户启动应用程序时,它将告诉已经运行的进程启动其默认功能。


我喜欢这个想法...如果加载发生在实际工作的同一进程中,那肯定会起作用...现在尝试从不同的进程中执行它... - Pierre-Olivier Goulet

0

你有几个选择。假设常见程序集具有强名称,它们可以放置在用户的全局程序集缓存 (GAC) 中。如果这些程序集是稳定的,你可以使用 ngen.exe 生成本机代码,这将为你提供所需的“预 JIT”功能。请搜索 GAC 和 ngen 以获取更多信息。

在问题更新后进行编辑:

以你寻求的方式加载程序集并不一定是最有效的方式 - 只要服务存在,这些程序集就会存在于服务的内存中,这可能对客户端机器造成负担。

我认为将程序集同时放入 GAC 和 ngen 是最好的选择,这两个步骤都可以自动化(假设服务正在使用适当的权限运行),通过检索程序集并使用 System.Diagnostics.Process 类进行外部调用 gacutil.exe 和 ngen.exe。

ngen.exe 的 MSDN 页面

gacutil.exe 的 MSDN 页面

关于Process类的MSDN页面


无法将它们放入GAC,因为它们驻留在网络上,并且它们并不真正稳定,因为我们仍在开发它们... - Pierre-Olivier Goulet
在这种情况下,我想不到任何避免在应用程序运行时加载和JIT组件的方法 - 我相信非GAC'd组件不会在应用程序域之间共享。 - Ben
我认为GAC中的程序集在没有指定加载行为(multidomainhost)的情况下仍然不会被共享:http://msdn.microsoft.com/en-us/library/system.loaderoptimizationattribute.aspx - Mike Cheel

0
你需要的是NGEN,它可以为你预编译程序集。我认为你可能会遇到的问题是这些程序集来自网络,并且可能被加载到不同的CPU架构中。NGEN应该在目标计算机上运行,因为它会为该计算机使用的特定架构进行编译和优化。
你可以考虑给这些程序集命名并将它们安装到每台计算机的GAC中。
我不认为你考虑的方法会奏效,我认为你会将它们加载到服务进程中,一旦它们被释放,系统就会清理它们,最终结果是没有速度提升。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接