0

I need to change the state management from inProc to StateServer in old application.

There is method that execute within a new thread.

The code look like as follows.

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

When the web garden is enabled the usage of session variables to update the status does not work as expected.

  • I have tried using class variable instead of session variables.
  • Used Cache instead of session.

None of them worked for me.

Note: This code is from a existing application that was developed at least 8 years ago.

I only want to run this in web garden without breaking the functionality.

Sanke
  • 676
  • 2
  • 13
  • 30
  • 3
    You gain nothing by using that thread, web requests already execute in their own thread. If you want to execute a long-running job, that was the wrong way to do it 8 years ago as well and only worked by chance - IIS knows nothing about that thread so it's free to GC any resources as soon as the request completes. The session may be closed while that thread is still running. Check [The Dangers of implementing recurring background tasks in ASP.NET](https://haacked.com/archive/2011/10/16/the-dangers-of-implementing-recurring-background-tasks-in-asp-net.aspx/) – Panagiotis Kanavos Sep 29 '20 at 08:15
  • Also check [How to run background tasks in ASP.NET](https://www.hanselman.com/blog/HowToRunBackgroundTasksInASPNET.aspx) which shows the available mechanisms for long-running jobs. The question doesn't show any *actual* work being done, only some risky control updates, so it's hard to recommend one technique or another. Perhaps the thread isn't needed at all? Perhaps you can use async/await? Perhaps you do need a way to run a long job and *explicitly* pass the data to it? – Panagiotis Kanavos Sep 29 '20 at 08:18
  • Is the real question how to report progress to keep track of a long running job and show it to the user? And display it in response to an ASP.NET Old update panel poll? That job is going to run even if no session is alive, so using the session is risky. Polling is expensive too, which is why applications use SignalR instead, to send messages to the browser from the client. – Panagiotis Kanavos Sep 29 '20 at 08:21
  • @PanagiotisKanavos Thank you for the comments. That explains a lot. For this application SingleR is not an option. Also, I am not willing do any drastic changes to the code that ran for 8 years. – Sanke Sep 29 '20 at 09:02
  • Then your only option is to leave it as is, because you won't be able to run it in a web garden without making those changes. – Ian Kemp Sep 29 '20 at 09:48

1 Answers1

0

I created a database table and store the values there instead of the session vars. There I used a GUID+KEY to identify the correct value in DB.

I created a method to delete the records in db when the process completes, in that way the searching cost in the DB is reduced.

Note: There is a considerable cost of writing to db and retrieving it.

This may be not the perfect solution for this. But this can be considered as a high-cost workaround.

Sanke
  • 676
  • 2
  • 13
  • 30