Стоит ли беспокоиться о отложенной загрузке в веб-приложении? - PullRequest
0 голосов
/ 06 мая 2009

Я узнал, что для одноэтапной ленивой загрузки используется следующий шаблон:

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 ]

4 голосов
/ 06 мая 2009

Ленивая загрузка обычно подразумевает, что вы лениво загружаете что-то из базы данных. То, что вы делаете, обычно называется « отложенная инициализация » (технически «отложенная инициализация» - это метод реализации шаблона отложенной загрузки).

Что касается ваших первоначальных вопросов: во-первых, вам не нужен синглтон. Если вам все еще это нужно, вот , как это должно быть сделано правильно. В-третьих, вам не нужен синглтон.

3 голосов
/ 06 мая 2009

Если у вас нет статических методов, которым не нужен синглтон, достаточно просто включить статический конструктор, чтобы сделать класс ленивым. Без статического конструктора он все еще в основном ленивый.

См. Мою страницу реализации синглтона для получения более подробной информации и опций.

Обычно я бы дал код, который вы дали в нижней части вопроса - он достаточно ленив, если вы действительно не хотите инициализировать синглтон, если он не будет использоваться. (В основном, с установленным beforefieldinit, JIT обычно гарантирует, что каждый тип, используемый в методе, инициализируется; без beforefieldinit он должен ждать до первого фактического использования класса во время выполнения. См. Мой beforefieldinit page для получения дополнительной информации - но важный момент заключается в том, что он по-прежнему не будет инициализировать все синглтоны, как только будет загружена сборка, или что-то в этом роде.)

1 голос
/ 06 мая 2009

Это все хорошо, но смысл ленивой загрузки - избегать загрузки (как правило, неуправляемых) ресурсов (попадания в базу данных, файловую систему и т. Д.) До тех пор, пока вам это не понадобится, что позволяет избежать их приоритетной загрузки при это действительно нужно. Использование одноэлементного шаблона само по себе не обязательно подразумевает ленивую загрузку, поскольку вы можете совершенно правильно создать управляемый экземпляр в любой точке.

Аспект отложенной загрузки вступает в игру, если к любым загружаемым ресурсам обращаются только при соответствующем вызове метода; если, когда этот экземпляр синглтона создается, он выполняет целую кучу запросов к базе данных и сохраняет результат, то это не ленивая загрузка, насколько я понимаю.

Что касается сценариев ORM, ленивая загрузка обычно относится непосредственно к отложению загрузки другого объекта в отношениях до первого доступа, что позволяет избежать выполнения второго, потенциально ненужного запроса.

Опять же, если вы знаете, что будете перемещаться по этим отношениям в ходе использования вами объекта (т. Е. Если вы получили User, чтобы перечислить их Posts или что-то в этом роде), тогда вы, вероятно, захотите дать команду вашему ORM загружать связанные объекты одновременно, что обычно дает подсказку для выполнения одного запроса с объединением, а не для циклического выполнения и выполнения нескольких запросов позже; в этом случае вам не нужна ленивая загрузка.

0 голосов
/ 06 мая 2009

Следите за тем, чтобы не перепутать загрузку страницы, сеанс и время жизни приложения. Тем не менее, вы уверены, что хотите использовать статический одноэлементный экземпляр? После создания он будет действовать до тех пор, пока приложение (веб-сервер) не будет закрыто или вы не запустите iisreset .

Попробуйте вместо этого кэшировать его в HttpContext.Current.Items, если вы хотите, чтобы один лениво загруженный экземпляр загружался на страницу, или, возможно, в HttpContext.Current.Session, если вы хотите один для пользователя.

...