Статические поля vs Переменные сеанса
До сих пор я использовал Session для передачи некоторых переменных с одной страницы на другую. Например, роль пользователя. Когда пользователь регистрируется в веб-приложении, идентификатор роли пользователя хранится в сеансе и эта роль проверяется в разных частях приложения. Я недавно начал думать, почему бы не использовать статические члены. Я могу хранить одну и ту же информацию в статическом поле и легко обращаться к ней в любом месте своего приложения (где бы ни было пространство имен, в котором находится это статическое поле.) Я знаю, что иногда использование переменных Session иногда бывает полезным, например:
- Любой вид данных может храниться в сеансе. Затем он должен быть запущен. Но статические поля принимают данные только с правильным типом данных.
- Переменные сеанса истекают через определенное время, которое во многих случаях является поведением.
Помимо вышеизложенного, существуют ли другие причины, по которым я не должен использовать статические поля для хранения данных и иметь их везде?
Ответы
Ответ 1
Нет, использование статических переменных для этого не способ:
- Если ваш AppDomain переработан, все ваши статические переменные будут "reset"
- Статические переменные не масштабируются горизонтально - если вы загружаете баланс вашего приложения, пользователь, который попадает на один сервер, то другой не будет видеть хранилище данных в статических переменных на первом сервере
- Самое главное, что статические переменные будут совместно использоваться всем доступом к этому серверу... он не будет использоваться для каждого пользователя... тогда как из вашего описания вы не хотите, чтобы пользователь X видел пользователя Y.
По сути, у вас есть два варианта распространения информации вокруг вашего приложения:
- Держите его на стороне клиента, поэтому каждый запрос предоставляет информацию из предыдущих шагов. (Это может стать громоздким с большим объемом информации, но может быть полезно для простых случаев.)
- Хранить на стороне сервера, в идеале, на каком-то постоянном уровне (например, в базе данных) с клиентом, предоставляющим идентификатор сеанса.
Если вы можете использовать балансировку нагрузки, чтобы все пользователи переходили на один и тот же сервер, и если вы не упускаете из виду, что сеансы теряются, когда AppDomain перерабатывается 1 или сервер идет вниз, вы может хранить его в памяти, с помощью идентификатора сеанса... но будьте осторожны.
1 В ASP.NET могут существовать механизмы, чтобы выжить, распространяя информацию сеанса от одного приложения до другого - я не уверен
Ответ 2
Это две разные вещи.
- Сессия может использоваться вне процесса (важна для балансировки нагрузки)
- Сессия может быть более долговечной из-за отсутствия возможностей процесса.
- ASP.Net автоматически управляет сеансом concurrency.
- Доступ к статическим переменным должен быть синхронизирован вручную.
- Статический глобальный для всего домена приложения. Если вы установите значение статического поля/свойства для одного пользователя, все пользователи получат одинаковое значение. Нежелательное поведение в вашем сценарии.
Любой вид данных может храниться в сеансе. Затем он должен быть отброшен однако статические поля принимают данные только с правильным типом данных.
Часто полезно абстрагировать значения Session со вспомогательным классом. Это может улучшить тестируемость, а также позволяет сильно набирать свойства и выполнять литье во внутренних элементах класса.
Пример:
public List<int> UserRoles
{
get
{
// optionally check that the value is indeed in session, otherwise this
// will throw
return (List<int>)Session["UserRoles"];
}
}
См. также:
Ответ 3
Вы забываете одно (я думаю)
Статические данные будут одинаковыми для всех пользователей приложения, тогда как сеанс "для пользователя".
Итак, для вашего сценария "Роль пользователя" я ожидаю смешные результаты;)
Ответ 4
Статические поля будут доступны для всех пользователей.
В качестве веб-среды у вас будет несколько потоков, работающих вместе.
Обновление любых статических элементов потребует правильного управления concurrency. Сделано неправильно, это значительно снизит производительность вашего сайта.
Сеансы могут быть перенесены из процесса и переданы через веб-ферму.
Сессии с proc будут существовать, даже если ваш сервер приложений разбился.