2012-01-18 4 views
52

Я храню некоторую информацию в статических переменных, определенных в классе страниц (а не в Global.asax). Я объявляю только переменную в коде:Пожизненная статическая переменная ASP.NET

protected static int SomeGlobalUnsecureID; 
protected static string SomeGlobalUnsecureString; 

и определить переменную в событии PageLoad. Например, я проверяю идентификатор из базы данных, если он отличается от SomeGlobalUnsecureID, я обновляю SomeGlobalUnsecureID и String из другого места, в противном случае оставляю их как есть. Это совершенно безопасно в моем приложении. логика (т. е. эти данные небезопасны, каждый может получить к ним доступ, без проблем); Единственное, что я хочу сделать это

  1. Держите одинаковое количество памяти, независимо от пользователей, подключенным

  2. Изменения тогда и только тогда, когда настойчивая информация отличается от того, в «памяти» (потому что на самом деле чтение строка отнимает много времени для меня.

Теперь, так как я делаю чек в PageLoad, у меня нет никаких проблем в перезагружаются страниц. Однако моя страница полна WebMethods, а иногда я вижу ТНА t статические переменные обнуляются. И странная часть; сеанс по-прежнему активен, даже если статические переменные обнулены (so-> нет перезапуска сервера или приложения пула и т. д.)

Это действительно странно для меня. Я предполагаю, что статическая переменная будет содержать свое значение до тех пор, пока приложение (каким-то образом) не закончится. Но даже сеанс не закончился, статическая переменная обнуляется. Что ты предлагаешь? Использует ли переменные приложения лучший выбор? Все документы, которые я читал в Интернете, предлагают статические переменные вместо переменных приложения, нужно ли их объявлять как-то иначе?

+1

Объявления в верхней части вашего вопроса: * не * статические, кстати. –

+1

:) ok, исправлено –

+1

'определить переменную в событии PageLoad.' Я думаю, вы имеете в виду инициализацию? Определение переменной - это то, что вы делаете, когда пишете 'protected static int Something;' –

ответ

73

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

По этим причинам, если система решит перезапустить или заменить класс (.NET doesn't kill or unload classes/assemblies in a running app domain тогда ваши статические переменные будут сброшены, потому что вы получаете новый класс с перезапуском или замены. Это относится и к ASPX страниц и classes in the App_Code folder

ASP.NET заменит класс, если по какой-либо причине считается, что его необходимо перекомпилировать (see ASP.NET dynamic compilation.

Вы не можете предотвратить потерю статических переменных из домена приложения, но вы можете попытаться избежать его из замены класса Вы можете поместить свои статические переменные в класс, который не является страницей aspx и не находится в каталоге App_Code. может захотеть разместить их на static class где-нибудь в вашей программе.

public static class GlobalVariables 
{ 
    public static int SomeGlobalUnsecureID; 
    public static string SomeGlobalUnsecureString; 
} 

Статические переменные в пуле, то есть означает, что если у вас есть 2 бассейна, который работает ваш asp.net сайт, у вас есть 2 разные статические переменные. (Web garden mode))

Статические переменные теряются, если система перезапускает приложение asp.net одним из этих способов.

  1. пул решает, что необходимо произвести перекомпиляцию.
  2. Вы открываете файл app_offline.htm
  3. Вы делаете ручной перезапуск бассейна
  4. Бассейн достичь каких-то ограничений, которые вы определить и сделать рестарт.
  5. По какой-либо причине вы перезапускаете iis или пул.

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

Поскольку перезапуск приложения перезагружает вашу статистику, несмотря ни на что, если вы действительно хотите сохранить свои данные, вы должны хранить данные в базе данных с помощью пользовательских классов. Вы можете хранить информацию для каждого пользователя в Session State с помощью database session state mode. Состояние/переменные приложения ASP.NET не помогут вам, потому что they are stored in memory, not the database, поэтому они также потеряны при перезагрузке домена приложения.

+0

. Каков наилучший подход для хранения данных постоянных приложений, подобных этому, какого-то внешнего хранилища кеширования? –

+0

@ DanielPowell Depend. В моей программе у меня много пулов и много потоков, общие для всех данных потоков, сохраненных в базе данных. Общие данные для каждого приложения сохраняются в глобальном статическом классе. – Aristos

+0

одна последняя вещь; Я создал статический класс с именем global и добавил в него свойства. работает нормально в коде .cs, но в aspx я не могу получить доступ к глобальному классу с помощью <% = global.someproperty%>, хотя они находятся в одном пространстве имен. это нормально? –

-5

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

protected void Page_Load(object sender, EventArgs e) 
{ 
    sss s1, s2; 
    s1 = new sss(); 
    s1.TotalMark = 10; 
    s2 = new sss(); 
    s2.TotalMark = 20; 
    sss.SchoolName = "St.Joseph's Hr.Sec.S"; //We can access through class and assign common to all 
    s1.PrintData(); 
    s2.PrintData(); 
} 

public class sss 
{ 
    public static string SchoolName { set; get; } 
    public int TotalMark { set; get; } 
    public string StudentName{set;get;} 
    public void PrintData() 
    { 
     Console.WriteLine(TotalMark); 
     Console.WriteLine(SchoolName); 
     Console.WriteLine(StudentName); 
    } 
} 
+0

Вниз проголосовали, этот ответ не связан с вопросом. (ОП четко понимает, как должны работать статические переменные. - Вопрос в том, почему они работают некорректно.) - Кроме того, объяснение плохо сформулировано. – BrainSlugs83

4

Я думаю, что следующие две точки, также важны для жизни статических переменных:

1 - в бассейне приложения в расширенных настройках установите флажок «Переработка» -> «Регулярный интервал времени (минуты)». Значение по умолчанию - 1740, что означает, что каждые 29 часов ваши статические переменные теряются из-за утилизации пула приложений. Этот параметр используется для прекращения возможных утечек памяти. Я бы не стал изменять эту настройку.

2 - В дополнительных настройках пула приложений проверьте «Модель процесса» -> «Время ожидания ожидания (минуты)». Значение по умолчанию равно 20, что означает каждые 20 минут бездействия в пуле приложений, рабочие процессы прекращаются/приостанавливаются, что приведет к потере ваших статических переменных. Этот параметр используется для освобождения ресурсов, когда пул приложений не используется в течение некоторого времени. Вы можете установить его на 0, чтобы отключить таймаут.

+0

Спасибо. ** Утилизация ** была проблемой в моем случае. – Isaac