我们在工作中使用DevExpress进行用户界面开发。第一次打开一个包含DevExpress控件的表单时,会出现长时间的暂停(有时在某些客户端上会持续15-20秒)。在Visual Studio中,我可以看到在这个阶段加载了大量程序集。是否有一种方法可以在后台预加载这些程序集到AppDomain中,例如在登录屏幕弹出之前启动一个线程?
我们在工作中使用DevExpress进行用户界面开发。第一次打开一个包含DevExpress控件的表单时,会出现长时间的暂停(有时在某些客户端上会持续15-20秒)。在Visual Studio中,我可以看到在这个阶段加载了大量程序集。是否有一种方法可以在后台预加载这些程序集到AppDomain中,例如在登录屏幕弹出之前启动一个线程?
另一种选择是强制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方法移动到登录表单并从构造函数调用即可。
这样做会导致用户每次启动时都要承受这种影响。
一般来说,这是一个不好的想法(如果您必须执行此操作,至少将其推迟到真正需要它的时候)。如果存在强烈的可能性他们在不久的将来将使用该功能,但系统其他方面处于空闲状态的情况下,这可能有所帮助。然而,要准确地做到这一点非常困难。
您可以查看是否有任何已加载的程序集在您的控制范围内并位于全局程序集缓存中。如果是,则可以对它们进行本机映像生成处理,这可能会对UI的这个方面的启动时间产生重大影响。
我不确定,但我猜测实际装载程序集并非耗时的部分,而是代码路径的JIT编译。也许您想查看ngen。这可能会解决性能问题,但请务必了解该工具的影响。
链接: - http://msdn.microsoft.com/en-us/library/6t9t5wcf.aspx - http://msdn.microsoft.com/en-us/magazine/cc163610.aspx
请查看Assembly.Load方法。
Gero