4

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

大多数大型应用程序第一次启动(冷启动)需要一段时间,比如 4-5 秒。随后的发射速度要快得多,几乎是瞬时的。我认为这与网络无关,因为最大的组件大约为 900KB,而且我们使用的是千兆网络。

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

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

基本上,我想做一些类似OpenOffice Quick starter的东西,但是对于我们自己的应用程序框架。

感谢大家!!!

---编辑---
这很有趣......似乎以正确的方式进行,但不确定我是否理解一切......

4

4 回答 4

2

您已经知道 JIT 编译不是问题,这也会减慢第二次启动的速度。您所要做的就是在文件系统缓存中获取 DLL。这样当您稍后启动程序时,它将使用缓存中的该 DLL 的副本,而不是通过网络连接的驱动器进行挖掘来找到它。这需要时间。Office 快速入门使用相同的技巧。如果所有这些预加载的东西不再适合,不确定谁会赢。

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

于 2010-10-21T18:47:51.033 回答
1

您可以使用以下文章中描述的技术以编程方式预jit 程序集:动态预编译(pre-JIT)您的程序集,或提前触发JIT 编译。

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

于 2010-10-21T17:48:46.350 回答
0

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

问题更新后编辑:

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

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

ngen.exe的 MSDN 页面

gacutil.exe的 MSDN 页面

Process 类的 MSDN 页面

于 2010-10-21T17:29:07.943 回答
0

您想要的是NGEN,它为您预编译程序集。我认为您将遇到的问题是来自网络的程序集,并且可能会为不同的 CPU 架构加载。NGEN 应在目标计算机上运行,​​因为它针对计算机使用的特定架构进行编译和优化。

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

我认为您正在考虑的方法行不通,我认为您会将它们加载到服务进程中,一旦它们被释放,它们将被系统清理,最终结果将是 no速度增加。

于 2010-10-21T17:32:28.690 回答