【发布时间】:2009-02-14 10:47:44
【问题描述】:
在工作中,我们使用 DevExpress 作为用户界面。第一次打开使用 DevExpress 控件的表单时,会有很长的停顿(有时在某些客户端上为 15-20 秒)。在 Visual Studio 中,我可以看到在该阶段正在加载大量程序集。有没有办法将这些程序集预加载到后台的 AppDomain 中,例如在登录屏幕弹出之前产生的线程上?
【问题讨论】:
标签: c# .net optimization assemblies
在工作中,我们使用 DevExpress 作为用户界面。第一次打开使用 DevExpress 控件的表单时,会有很长的停顿(有时在某些客户端上为 15-20 秒)。在 Visual Studio 中,我可以看到在该阶段正在加载大量程序集。有没有办法将这些程序集预加载到后台的 AppDomain 中,例如在登录屏幕弹出之前产生的线程上?
【问题讨论】:
标签: c# .net optimization assemblies
另一种选择是强制 JIT 异步加载程序集,而不是手动加载。诀窍是简单地调用控件的构造函数,这样 Jit 就知道它必须开始编译那个特定的代码路径。通常这会迫使它加载所有依赖的程序集。只需确保用 try catch 包围构造函数的调用即可。
如何在加载时执行此操作的示例:
static class Program
{
/// <summary>
/// The main entry point for the application.
/// </summary>
[STAThread]
static void Main()
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
PreJitControls();
Application.Run(new Form1());
}
private static void PreJitControls()
{
ThreadPool.QueueUserWorkItem((t) =>
{
Thread.Sleep(1000); // Or whatever reasonable amount of time
try
{
AssemblyPullingControl1 c = new AssemblyPullingControl1();
}
catch (Exception) { }
try
{
AssemblyPullingControl2 c = new AssemblyPullingControl2();
}
catch (Exception) { }
});
}
}
但您也可以在登录表单的构造函数中执行类似的操作,如果这是进行预加载的更好时机。只需将 PreJitControls 方法移动到登录表单并从构造函数中调用它。
【讨论】:
然而,这将迫使您的用户始终在启动时接受该打击。
一般来说这是一个坏主意(如果你有命中至少推迟到你真的需要它)。如果他们很有可能在不久的将来打算使用该功能但系统处于空闲状态,则可能会有所帮助的情况是触发负载。但是,这可能很难准确地做到。
您可能会看到任何已加载的程序集是否在您的控制之下和 GAC 中。如果是这样,您可以生成它们,这可能会对您的 UI 这方面的启动时间产生重大影响。
【讨论】:
我不确定,但我猜不是程序集的实际加载是耗时的部分 - 但可能是代码路径的 JIT 编译。也许你想看看ngen。可能是它使性能问题消失了。但请务必了解该工具的含义。
链接: - http://msdn.microsoft.com/en-us/library/6t9t5wcf.aspx - http://msdn.microsoft.com/en-us/magazine/cc163610.aspx
【讨论】:
看看 Assembly.Load 方法。
格罗
【讨论】:
如果您想更快地获得程序集,为什么不查看 NGEN 的代码。 Pre JIT 一切都在后台。这有优缺点,但取决于您的应用在做什么。
【讨论】: