如何预加载.net程序集

时间:2010-10-21 17:25:27

标签: .net clr preload

在我的工作中,我们正在使用.net框架4开发不同的应用程序。所有应用程序都使用我们开发的通用程序集,例如data.dll中的数据层。这些应用程序驻留在网络驱动器上,并直接从那里启动。

大多数大型应用程序需要一段时间,比如4-5秒,才能首次启动(冷启动)。随后的发布会更快,几乎是即时的。我不认为它与网络有关,因为最大的组装大约是900KB,我们使用的是千兆网络。

我想创建一个在计算机启动时启动的服务,并将所有.net程序集加载到特定目录下。我希望当用户启动程序时,所有必需的程序集都已加载并“JITed”,因此启动应该更快。

我知道如何创建服务,但我想知道这是否可行,因为我对CLR的理解非常有限...而且,会像Assembly.LoadFrom(fileName)这样做来预加载程序集?如果我暂时不启动任何程序,它们会保持加载状态还是一段时间后自行卸载?如果我更改已加载的程序集会发生什么?

基本上,我想做OpenOffice Quick starter之类的事情,但是对于我们自己的应用程序框架。

谢谢大家!!!

--- --- EDIT
This is interresting...似乎以正确的方式进行,但不确定我理解一切......

4 个答案:

答案 0 :(得分:2)

你已经知道JIT编译不是问题,这也会减慢第二次启动。您所要做的就是在文件系统缓存中获取DLL。因此,当您稍后启动程序时,它将使用缓存中的DLL副本,而不是通过网络连接驱动器来查找它。这是需要时间的。 Office Quick Start使用相同的技巧。如果所有这些预装的东西都不适合,不确定谁会赢。

只需创建一个Winforms应用程序,这样你就不会得到一个窗口,并调用Assembly.Load()来加载程序集,File.ReadAllBytes()以确保整个内容都在缓存中。在Startup文件夹中放置此程序的快捷方式。你提到的那个程序集足够大,可以从Ngen.exe的热启动中获得提升。这必须在每个工作站上运行。

答案 1 :(得分:1)

您可以使用以下文章中描述的技术以编程方式预先装配装配体:Pre-compile (pre-JIT) your assembly on the fly, or trigger JIT compilation ahead-of-time.

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

答案 2 :(得分:0)

您有几种选择。假设公共程序集具有强名称,则可以将它们放在用户的全局程序集缓存(GAC)中。如果这些程序集是稳定的,您可以使用ngen.exe生成本机代码,这将为您提供所需的“预JIT”。 Google GAC和ngen了解更多信息。

问题更新后编辑:

以您正在寻找的方式加载程序集不一定是最有效的方式 - 只要服务在周围,这些程序集将存在于您的服务内存中,这可能会或可能不会成为客户端的负担机。

我相信GAC和你的程序集的组合是最好的选择,并且通过检索程序集和进行外部调用,这两个步骤都可以自动化(假设服务以适当的权限运行)使用System.Diagnostics.Process类到gacutil.exe和ngen.exe。

ngen.exe

的MSDN页面

gacutil.exe

的MSDN页面

Process class

的MSDN页面

答案 3 :(得分:0)

你想要的是NGEN,它为你预先编译了程序集。我认为您将遇到的问题是来自网络的程序集,并且可能正在为不同的CPU体系结构加载。 NGEN应该在目标计算机上运行,​​因为它可以编译并优化计算机使用的特定体系结构。

您可能会考虑为程序集提供强名称,并将它们安装到每台计算机上的GAC中。

我认为您正在考虑的方法不会起作用,我认为您将把它们加载到服务流程中,一旦它们被释放,它们将被系统清理,最终结果将不会加速。