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

В моем page1.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 ссылается на Session, поэтому она автоматически обновляется в сеансе (HashTable не требуется для переназначения ее обратно в сеанс).

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

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

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

3 ответа

Решение

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

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

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

  1. Использовать режим inProc
  2. Сохраняйте словарь в своем классе потока с ключом в качестве идентификатора сеанса, а значением является ваша хеш-таблица, поэтому, если page2.aspx захочет прочитать значение хеш-таблицы, он передаст свой идентификатор сеанса методу и вернет требуемое значение.

Я бы явно SET и GET SessionState так:

В твоей ветке Run

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

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

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

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

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

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

Или создайте отдельное значение сеанса для количества страниц на странице Page1, в то же время делая все остальное. (РЕДАКТИРОВАТЬ: не важно вторая часть, это то, что Рене предложил ниже).

Другие вопросы по тегам