Обновление переменных сеанса Asp.net по потоку не отражается в сеансе

В моей странице1.aspx я создаю отчет из базы данных с помощью потока.

//on button click
Hashtable ht = (Hashtable)Session["ReportParam"];
ReportThreadClass rth = new ReportThreadClass(ht);
Thread thread = new System.Threading.ThreadStart(rth .Run);
thread.Start();

В методе рома моего класса потока я обновляю значения в Hashtable, сколько страниц я создал.

//in thread' method        
public virtual void Run()
{      
    int pagecount=0;
    while(done)
    {
        //loading data from DB and generating html pages

        ht["Total_Pages"] = pagecount;
    }
}

На моем Page2.aspx я читаю значения из переменной сеанса

Hashtable ht = (Hashtable)Session["ReportParam"];
int TotalPages = (int) ht["Total_Pages"];

Когда я запускаю приведенный выше код в режиме InProc, все работает нормально, я получаю обновленные значения из сеанса. Поскольку каждая вещь хранится в статической переменной, и на ht ссылается сеанс, поэтому он автоматически обновляется в сеансе (HashTable не требуется, чтобы переназначить его обратно в сеанс).

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

Но значение Total_Pages не обновляется в Page2.aspx даже после полного запуска потока.

Итак, есть ли какое-либо событие или метод, который запускается для сохранения всех обновлений в переменной сеанса на State-Server, если да, то, пожалуйста, сообщите мне. если нет, то, пожалуйста, предложите мне какую-нибудь идею, чтобы получить обновленное значение в page2.aspx.


person Pavan Tiwari    schedule 16.05.2013    source источник
comment
Как вы называете свой Page2.aspx   -  person user1130157    schedule 16.05.2013
comment
Я постоянно вызываю его из Jquery, пока он полностью не загрузит все страницы.   -  person Pavan Tiwari    schedule 16.05.2013
comment
Когда вы запускаете в режиме OutProc и пытаетесь выполнить отладку, возникает ли второе событие Session_Start при запуске Page2.aspx?   -  person Alexander    schedule 18.06.2013
comment
Нет нового поколения идентификатора сеанса, я получаю объект сеанса, но не обновляю его, который обновляется потоком.   -  person Pavan Tiwari    schedule 19.06.2013


Ответы (3)


В режиме Out Proc Mode сеанс сохраняется после некоторого события, поэтому, если ваш поток обновляет переменные сеанса, он не будет сохраняться в хранилище.

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

Итак, у вас есть два решения для этой ситуации

  1. Использовать режим inProc
  2. Поддерживайте словарь в своем классе потоков с ключом в качестве идентификатора сеанса, а значением является ваша хеш-таблица. Поэтому, если page2.aspx хочет прочитать значение хэш-таблицы, он передаст свой идентификатор сеанса методу, который вернет требуемое значение.
person user1130157    schedule 19.06.2013
comment
Да, но это не решение. если я ничего не найду, я выберу второе решение, предложенное пользователем @user1130157. - person Pavan Tiwari; 19.06.2013
comment
Я думаю, что в режиме OutProc я могу сделать все вышеперечисленное, поэтому, наконец, я использую ваше второе решение. - person Pavan Tiwari; 20.06.2013
comment
имейте в виду, что вариант 2 может работать и выключаться, если вы находитесь в сценарии веб-фермы без настройки липкой сессии... - person rene; 20.06.2013

Я бы явно SET и GET SessionState следующим образом:

В вашей теме

// no complex object like hastable, just a plain value...
Session["pageCount"] = pageCount;

В вашей странице2.apsx:

var pageCount = (int) Session["pageCount"]??0;

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

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

person rene    schedule 16.06.2013
comment
Это не сработает, потому что в режиме OutProc значения сеанса сохраняются в постоянном хранилище после Request_EndEvent, поэтому даже я помещаю простую переменную в сеанс после этого события, это не сработает. - person Pavan Tiwari; 18.06.2013

Менее эффективно, но я бы, вероятно, просто пропинговал базу данных для подсчета страниц на странице 2.

Или создайте отдельное значение сеанса для количества страниц на странице 1 одновременно с выполнением всего остального. (EDIT: не говоря уже о второй части, это то, что Рене предложил ниже).

person Matthew Price    schedule 18.06.2013
comment
Я храню данные на Stat-сервере. Все данные сеанса сохраняются на Stat-сервере после события End_request, но мой поток все еще выполняется после этого события. Итак, как я могу запросить Stat-сервер, если мое значение не хранится на State-сервере, потому что выполнено событие end_request. - person Pavan Tiwari; 19.06.2013