Шаблон "одиночка" в веб-приложениях

Я использую шаблон "одиночка" для datacontext в моем веб-приложении так, чтобы я не инстанцировал его каждый раз, когда однако я не уверен, как веб-приложения работают, IIS открывает поток для каждого соединенного пользователя? если так, что было бы, произошел, если мой одиночный элемент не ориентирован на многопотоковое исполнение? Кроме того, это в порядке для использования шаблона "одиночка" для datacontext? Спасибо.

11
задан Pointy 7 March 2010 в 22:42
поделиться

5 ответов

Многие люди хранят DataContext на протяжении всего запроса, сохраняя его в HttpContext.Current.Items Таким образом, он также частный к запросу.

Взгляните на это сообщение в блоге Стива Сандерсона и шаблон UnitOfWork n.

8
ответ дан 3 December 2019 в 03:04
поделиться

@ryudice веб-сервер создает новый поток для каждого запроса. Я думаю, что лучший подход - привязать текст данных к каждому запросу, а это означает, что вы должны создавать новый текст данных каждый раз, когда обслуживаете запрос. Хороший способ добиться этого - использовать инструмент DI, такой как StructureMap . Такие инструменты позволяют вам настроить жизненный цикл экземпляров, которые вы настраиваете, поэтому, например, в вашем случае вы должны настроить свой класс XDataContext на HttpContext.

С уважением.

1
ответ дан 3 December 2019 в 03:04
поделиться

вот примеры Microsoft того, как сделать многоуровневый с LINQ-To-SQL.

http://code.msdn.microsoft.com/multitierlinqtosql

0
ответ дан 3 December 2019 в 03:04
поделиться

Я использую одноэлементный шаблон для контекста данных в моем веб-приложении

"Синглтон" может означать много разных вещей в этом контексте. Один экземпляр на запрос? За сеанс? По потоку? Для каждого домена приложения ( статический экземпляр)? Последствия всего этого кардинально различны.

Одноэлементный запрос на запрос (хранящийся в HttpContext ) подойдет. Использование синглтона за сеанс не рекомендуется, но его можно заставить работать. Может показаться, что синглтон на поток работает, но может привести к неожиданному и трудному для отладки поведению. Синглтон для каждого приложения или AppDomain - это ожидающая катастрофа катастрофа.

, так что мне не нужно создавать его каждый раз

Создание DataContext очень и очень дешево. Метаданные кэшируются глобально, и соединения не создаются, пока вы не выполните запрос. Нет причин пытаться оптимизировать создание экземпляра DataContext .

однако я не уверен, как работают веб-приложения, открывает ли IIS поток для каждого подключенного пользователя?

IIS использует разные потоки для каждого запроса, но один запрос может использовать несколько потоков, и потоки берутся из пула потоков, что означает, что в конечном итоге один и тот же пользователь будет иметь запросы во многих разных потоках, и, наоборот, разные пользователи будут совместно использовать один и тот же поток в течение нескольких запросов и в течение длительного периода времени. Вот почему я упоминал выше, что вы не можете полагаться на локальный синглтон потока.

если так, что бы случилось, если бы мой синглтон не был потокобезопасным?

Очень плохие вещи. Все, что вы кэшируете глобально в приложении ASP.NET, необходимо либо сделать потокобезопасным, либо заблокировать во время использования.

Кроме того, можно ли использовать одноэлементный шаблон для контекста данных? Спасибо.

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

Экземпляры DataContext должны быть ограничены областью одного метода, когда это возможно, с использованием предложения using . Лучше всего хранить их в HttpContext . Если необходимо, вы можете сохранить его в сеансе, но есть много вещей, о которых вам нужно знать (см. этот вопрос Я недавно ответил на ObjectContext - почти все те же принципы применяются к DataContext ).

Но, прежде всего, не создает «глобальные» одноэлементные экземпляры DataContext в приложении ASP.NET. Позже вы сильно пожалеете об этом.

13
ответ дан 3 December 2019 в 03:04
поделиться

Статические переменные видны всем пользователям домена приложения, а не сеанса. После создания переменная будет находиться в памяти в течение всего времени существования домена приложения, даже если нет активных ссылок на объект.

Итак, если у вас есть какая-то информация о состоянии в веб-приложении, которая не должна быть видна другим пользователям, она должна быть абсолютно , а не статической. Вместо этого сохраните такую ​​информацию в пользовательском сеансе или преобразуйте свою статическую переменную примерно в это:

public static Data SomeData
{
    get
    {
        if (HttpContext.Session["SomeData"] == null)
            HttpContext.Session["SomeData"] = new Data();
        return (Data)HttpContext.Session["SomeData"];
    }
}

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

Кроме того, если у вас есть информация о состоянии в статической переменной, вам потребуется какая-то синхронизация для ее изменения, иначе вам придется распутывать кошмар условий гонки.

7
ответ дан 3 December 2019 в 03:04
поделиться
Другие вопросы по тегам:

Похожие вопросы: