Термін служби статичної змінної ASP.NET


78

Я зберігаю деяку інформацію у статичних змінних, визначених у класі сторінки (не в Global.asax). Я оголошую змінну лише в коді, як:

protected static int SomeGlobalUnsecureID;
protected static string SomeGlobalUnsecureString;

і визначити змінну в події PageLoad. Наприклад, я перевіряю ідентифікатор з бази даних, якщо він відрізняється від SomeGlobalUnsecureID, я оновлюю SomeGlobalUnsecureID і String звідкись ще, інакше залишаю їх як є. Це абсолютно безпечно в моєму додатку. логіка (тобто ці дані не захищені, кожен може отримати до них доступ, не проблема); єдине, що я хочу досягти - це

  1. Тримайте однакову кількість пам'яті незалежно від підключених користувачів

  2. Змінюйте тоді і лише тоді, коли постійна інформація відрізняється від тієї, що міститься в «пам'яті» (адже насправді читання рядка для мене займає багато часу.

Тепер, оскільки я роблю перевірку в PageLoad, у мене не виникає проблем із перезавантаженими сторінками. Однак моя сторінка повна WebMethods, і іноді я бачу, що статичні змінні обнулені. І дивна частина; сеанс все ще активний, навіть якщо статичні змінні обнулені (тому-> немає перезапуску сервера чи додатку. пулу тощо)

Для мене це справді дивно. Я припускаю, що статична змінна буде зберігати своє значення, поки додаток (якимось чином) не закінчиться. Але навіть термін дії сеансу не закінчився, статична змінна обнуляється. Що ти пропонуєш? Чи є кращим вибором використання змінних додатків? Усі документи, які я читав в Інтернеті, пропонують статичні змінні замість змінних додатків, чи потрібно мені оголошувати їх якимось іншим чином?


1
Декларації у верхній частині вашого запитання не є статичними, до речі.
Ендрю Барбер

1
'визначити змінну в події PageLoad.' Я думаю, ви маєте на увазі ініціалізувати? Визначення змінної - це те, що ви робите, коли пишетеprotected static int Something;
Carl G

"Тепер, оскільки я роблю перевірку в PageLoad, у мене не виникає проблем із перезавантаженими сторінками." - це звучить як умова перегонів, які чекають, що відбудуться. Натомість я б розглянув безпечну ліниву ініціалізацію.
milimoose

Статична затримка триває до наступної переробки. Помістіть свої змінні в статичний клас, використовуйте його в інших
Mbithy Mbithy

Відповіді:


106

Статичні змінні зберігаються протягом усього терміну дії домену програми. Отже, дві речі, які спричинять «скидання» ваших статичних змінних, - це перезапуск домену програми або використання нового класу. У вашому випадку зі статичними змінними, що зберігаються в класі aspx Page, ви можете втратити статичні змінні, коли ASP.NET вирішить перекомпілювати сторінку aspx в новий клас, замінивши старий клас сторінки новим.

З цих причин, якщо система вирішить перезапустити або замінити клас ( .NET не вбиває та не вивантажує класи / збірки в запущеному домені програми ), тоді ваші статичні змінні скидаються, оскільки ви отримуєте новий клас із перезапуском або заміною. Це стосується як сторінок aspx, так і класів у папці App_Code

ASP.NET замінить клас, якщо з будь-якої причини вважає, що потрібно перекомпілювати його ( див. Динамічну компіляцію ASP.NET ).

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

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

Статичні змінні належать до пулу, це означає, що якщо у вас є 2 пули, на яких працює ваш сайт asp.net, у вас є 2 різні статичні змінні. ( Режим веб-саду )

Статичні змінні втрачаються, якщо система перезапустить вашу програму asp.net одним із таких способів.

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

Ці статичні змінні не є безпечними для потоків, і вам потрібно використовувати ключове слово lock, особливо якщо ви отримуєте доступ до них із різних потоків.

Оскільки перезапуск програми скине вашу статику, незважаючи ні на що, якщо ви дійсно хочете зберегти свої дані, вам слід зберігати дані в базі даних за допомогою власних класів. Ви можете зберігати інформацію про кожного користувача у стані сеансу в режимі стану сеансу бази даних . Стан / змінні програми ASP.NET не допоможуть вам, оскільки вони зберігаються в пам'яті, а не в базі даних , тому вони також втрачаються при перезапуску домену програми.


6
@Aristos Це може бути старе запитання, але ваша відповідь не є точною. Якщо змінна класу є статичною, не має значення, скільки екземплярів цього класу ви створите та вб'єте, ця змінна буде зберігати своє значення, доки її збірка залишається завантаженою в пам'ять. Однак оскільки IIS регулярно переробляє розміщені програми, деякі збірки вивантажуються, а потім завантажуються знову, спричиняючи втрату даних статичної змінної. Погляньте на це
Thomas CG de Vilhena

1
@ ThomasC.G.deVilhena Я кажу (погоджуюсь) те саме з вами? Не добре набрав? Чи можете ви, будь ласка, відредагувати моє запитання та виправити цю частину, яку ви сказали?
Арістос,

1
Я думаю, проблема полягає в тому, що статичні змінні визначаються у файлі aspx (який повинен бути нестатичним класом.) Окрім перезапуску програми (що стирає всі статичні змінні), IIS також перекомпілює сторінки aspx (коли вони змінені, або, можливо, з інших причин), а потім завантажте нову скомпільовану збірку. Щойно скомпільована сторінка / клас aspx - це новий клас зі своїми статичними змінними. Перемикання змінних на статичний клас повинно запобігати скидання, крім випадків перезапуску програми, оскільки зараз для класу не відбувається перекомпіляція aspx.
Carl G

1
@ ThomasC.G.deVilhena Якщо ви хочете змінити якусь частину цієї відповіді, щоб зробити її більш точною, будь ласка, зробіть це.
Арістос

1
@CarlG Я пропоную вам те саме, якщо ви хочете змінити якусь частину цієї відповіді або додати деякі інші аспекти, щоб зробити її більш точною, будь ласка, зробіть це.
Арістос

21

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

1 - У розширених налаштуваннях пулу додатків встановіть прапорець "Переробка" -> "Регулярний інтервал часу (хвилини)". Значення за замовчуванням - 1740, що означає, що через кожні 29 годин статичні змінні втрачаються через переробку пулу ваших програм. Цей параметр використовується для припинення можливих витоків пам'яті. Я б не змінював це налаштування ..

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


1
Дякую. Проблемою в моєму випадку була переробка .
Ісаак

IMHO налаштування переробки за замовчуванням повинні бути змінені для більшості програм, оскільки вони "зміщуються" - я думаю, мені подобається ТОЧНО знати, коли пул буде перероблятися, не думаючи про це.
combatc2

-12

Статична змінна використовується для зберігання всього об'єкта з однаковим значенням

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);
    }
}

3
Якщо голосувати проти, ця відповідь не пов’язана з питанням. (ВП чітко розуміє, як мають працювати статичні змінні. - Питання в тому, чому вони не працюють належним чином.) - Крім того, пояснення сформульовано погано.
BrainSlugs83, 02
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.