预加载程序集

7

我们在工作中使用DevExpress进行用户界面开发。第一次打开一个包含DevExpress控件的表单时,会出现长时间的暂停(有时在某些客户端上会持续15-20秒)。在Visual Studio中,我可以看到在这个阶段加载了大量程序集。是否有一种方法可以在后台预加载这些程序集到AppDomain中,例如在登录屏幕弹出之前启动一个线程?

5个回答

4

另一种选择是强制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方法移动到登录表单并从构造函数调用即可。


2

这样做会导致用户每次启动时都要承受这种影响。

一般来说,这是一个不好的想法(如果您必须执行此操作,至少将其推迟到真正需要它的时候)。如果存在强烈的可能性他们在不久的将来将使用该功能,但系统其他方面处于空闲状态的情况下,这可能有所帮助。然而,要准确地做到这一点非常困难。

您可以查看是否有任何已加载的程序集在您的控制范围内并位于全局程序集缓存中。如果是,则可以对它们进行本机映像生成处理,这可能会对UI的这个方面的启动时间产生重大影响。


我计划在用户输入用户名和密码时,在后台线程中加载程序集,这样启动时就不会有明显的延迟。 - Rauhotz
除非: 1)始终需要这些dll文件 2)加载时间非常接近或少于他们登录所需的时间。 如果这两个条件都成立,这可能会有用... - ShuggyCoUk

1

暂停期间CPU使用率非常低。 - Rauhotz
嗯,我还是会尝试使用 ngen 进行预编译。它可以进行许多优化。也许启动成本就会消失。 - Tobias Hertkorn
不仅仅是 CPU 使用率的问题,还有它需要额外的磁盘 I/O。 - ShuggyCoUk

0

请查看Assembly.Load方法。

Gero


0
如果您想让程序集运行更快,为什么不考虑使用NGEN来编译您的代码呢?它可以在后台预先JIT编译所有内容。但这也有利有弊,具体取决于您的应用程序所做的事情。

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