我应该在网络应用程序中担心延迟加载吗?

时间:2009-05-06 10:44:05

标签: c# .net performance lazy-loading

我已经知道要使用单例延迟加载,这是要使用的模式:

private MyObject()
{
}

public static MyObject Instance
{
    get { return SingletonCreator.CreatorInstance; }
}

private static class SingletonCreator
{
    private static readonly MyObject _instance = new MyObject();

    public static MyObject CreatorInstance
    {
        get { return _instance; }
    }
}

但更简单的模式是:

private static readonly MyObject _instance = new MyObject();

private MyObject()
{
}

public static MyObject Instance
{
    get { return _instance; }
}

这不会是延迟加载。但这真的是我应该在网络应用程序中烦恼的事情吗?

4 个答案:

答案 0 :(得分:4)

延迟加载通常意味着你懒得从数据库加载一些东西。你正在做的通常被称为“lazy initialization”(技术上“懒惰初始化”是一种实现延迟加载模式的方法)。

关于你原来的问题:首先,你不需要单身人士。如果需要它,here's应该如何正确地完成此操作。第三,你不需要单身人士。

答案 1 :(得分:3)

除非你有不需要单例的静态方法,否则只需要包含一个静态构造函数就可以使类变得懒惰。如果没有静态构造函数,它仍然主要是懒惰。

有关详细信息和选项,请参阅我的singleton implementation page

我通常会在问题的底部给出你的代码 - 它很懒,除非你真的不想初始化单例,除非它会被使用。 (基本上使用beforefieldinit set,JIT通常会确保方法中使用的每个类型都已初始化;没有beforefieldinit它必须等到执行期间第一次实际使用该类。请参阅我的{ {3}}了解更多信息 - 但重要的是,一旦加载程序集或类似的东西,它仍然不会初始化所有单例。)

答案 2 :(得分:1)

这一切都很好,但延迟加载的重点是避免加载(通常是非托管的)资源(命中数据库,文件系统等),直到你需要为止,这样可以避免在你需要时先加载它们真的需要。单独使用单例模式本身并不一定意味着延迟加载,因为您可以在任何时候正确地创建托管实例。

如果只在进行适当的方法调用时访问您加载的任何资源,则延迟加载方面会起作用;如果,当创建单例实例时,它会执行一大堆数据库查询并保存结果,那么就我而言,它并不是延迟加载。

对于ORM场景,延迟加载通常直接指向关系中的另一个对象的加载,直到第一次访问为止,这避免了执行第二次可能不必要的查询。

然后,如果您知道在使用对象的过程中将要导航该关系(例如,如果您检索了User以便列出他们的Posts或者某事),那么你可能想要指示你的ORM同时加载相关的对象,这通常会提示它用连接执行单个查询,而不是循环并稍后执行多个查询;在这种情况下,你真的不想要延迟加载。

答案 3 :(得分:0)

请确保不要混淆页面加载,会话和应用程序生命周期。那就是说,你确定要使用静态单例实例吗?一旦创建,它将一直存在,直到应用程序(网络服务器)关闭或您运行 iisreset

如果您希望每页加载一个延迟加载的实例,或者如果您想要每个用户一个HttpContext.Current.Items,请考虑在HttpContext.Current.Session中缓存它。