Как использовать переменные сеанса с многопоточностью, где сеанс хранится на сервере состояний (веб-сад)

#c# #asp.net #.net #multithreading #web-garden

#c# #asp.net #.net #многопоточность #веб-сад

Вопрос:

Мне нужно изменить управление состоянием с InProc на StateServer в старом приложении.

Существует метод, который выполняется в новом потоке.

Код выглядит следующим образом.

 protected void btnTransaction_Click(object sender, EventArgs e)
{
    timerTrans.Enabled = true;
    timerTrans.Interval = 200;
    Thread thread = new Thread(new ParameterizedThreadStart(DoAllWork));
    thread.Start(dbConnectionString);
}

public void DoAllWork(object connectionString)
{
   DBAccess dba = new DBAccess(connectionString.ToString());
   Session["NextTransactionId"] = dba.getNewTransactionId();

   //Other work

   foreach(transaction t in transactions)
   {
       ShowTrasnactionStatus("Processing transaction " t.id);
   }

   //Other work

   Session["FinalStatus"] = "All Transactions Completed";
   Session["TransactionStatus"] = "Done";
}

private void ShowTrasnactionStatus(string statusMsg)
{
    Session["TransactionStatus"] = statusMsg;
}

protected void timerTrans_Tick(object sender, EventArgs e)
{
    lblStatus.Text = Session["TransactionStatus"].ToString();
    
    if (Session["TransactionStatus"].ToString() == "Done")
    {
         //Final Stage of Transaction Processing 
         lblStatus.Text = "Getting final status ...";
         billEndTime = DateTime.Now;

         ShowFinalStatus();
         timerBilling.Enabled = false;
    }
}
  

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

  • Я попытался использовать переменную класса вместо переменных сеанса.
  • Вместо сеанса используется кэш.

Ни один из них не работал для меня.

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

Я только хочу запустить это в веб-саду, не нарушая функциональность.

Комментарии:

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

2. Также проверьте, как запускать фоновые задачи в ASP.NET который показывает доступные механизмы для длительных заданий. Вопрос не показывает никакой фактической выполняемой работы, только некоторые рискованные обновления элементов управления, поэтому трудно рекомендовать тот или иной метод. Возможно, поток вообще не нужен? Возможно, вы можете использовать async / await? Возможно, вам нужен способ запустить длинное задание и явно передать ему данные?

3. Является ли реальным вопрос, как сообщать о ходе выполнения, чтобы отслеживать длительное выполнение задания и показывать его пользователю? И отображать его в ответ на ASP.NET Старый опрос панели обновлений? Это задание будет выполняться, даже если сеанс не активен, поэтому использование сеанса является рискованным. Опрос также обходится дорого, поэтому приложения вместо этого используют SignalR для отправки сообщений в браузер от клиента.

4. @PanagiotisKanavos Спасибо за комментарии. Это многое объясняет. Для этого приложения СинглеР не подходит. Кроме того, я не хочу вносить какие-либо радикальные изменения в код, который выполнялся в течение 8 лет.

5. Тогда ваш единственный вариант — оставить все как есть, потому что вы не сможете запустить его в веб-саду без внесения этих изменений.

Ответ №1:

Я создал таблицу базы данных и сохраняю там значения вместо переменных сеанса. Там я использовал КЛЮЧ GUID для определения правильного значения в БД.

Я создал метод для удаления записей в БД по завершении процесса, таким образом, стоимость поиска в БД снижается.

Примечание: запись в БД и ее извлечение сопряжены со значительными затратами.

Это может быть не идеальным решением для этого. Но это можно рассматривать как дорогостоящий обходной путь.