0

I have a web application that, based on input from a user, calculates a combination of products to fit the requirements and returns a quote for the user. This calculation can take some time, so I am displaying a progress dialog to the user.

The progress dialog is a UserControl with an UpdatePanel, that contains some text labels, a button, and a timer which is used for the AsynchPostBackTrigger trigger. This is declared on my aspx page but is hidden by default.

Before, I created a separate thread to do the heavy work while updating the progress dialog using the main thread. There were no issues there. here is where I start the thread:

    protected void StartQuoteCalculation(object sender, EventArgs e)
    {
        TotalPanelCount = CurrentQuote.PanelCount;
        ProgressDialog.ShowPopup();

        CalculateQuoteThread = new Thread(new ThreadStart(CalculateQuote));
        CalculateQuoteThread.Start();
    }

Where CalculateQuote does the heavy work.

However, I've recently had to change something unrelated to this exactly, but it is now affecting the calculation of the combinations.

A variable that's used during the quote calculation is now stored in the user Session. The session is lost when we start the worker thread above so when accessing this variable it was throwing a NullReference exception. To fix this, I've tried passing the HttpContext.Current to the new thread like so:

protected void StartQuoteCalculation(object sender, EventArgs e)
{
        TotalPanelCount = CurrentQuote.PanelCount;
        ProgressDialog.ShowPopup();

         HttpContext ctx = HttpContext.Current;
         CalculateQuoteThread = new Thread(new ThreadStart(() =>
             {
                 HttpContext.Current = ctx;
                 CalculateQuote();
             }));
         CalculateQuoteThread.Start();
}

However, the session seems to stay valid for a short while, but after a few seconds it is still throwing NullReferenceException. HttpContext.Current is valid, but the HttpContext.Current.Session is null.

So, I have a few questions:

  1. If it's possible to pass the HttpContext to the other thread, why is the Session going to null after short time? How can I prevent this?
  2. Is it possible to create, display and update the ProgressDialog panel in the new thread? (to keep the product calculation in the main thread with valid Session data)

I've tried a couple things on #2, but as I am not so knowledgable on asp.net and web development in general, I haven't been successful.

ChrisJ
  • 159
  • 14
  • Where are you passing the `HttpContext?` I don't see it. But `HttpContext` is specific to a request. It appears that you want to tie this to the session, not the request. So you could try passing the session instead. – Scott Hannen Jul 04 '16 at 15:54
  • @ScottHannen Apologies, I should have said 'passing HttpContext.Current to the new thread'. I'm assigning it in the constructor of the Thread, before calling CalculateQuote(). I got this solution from here: http://stackoverflow.com/questions/8925227/access-httpcontext-current-from-different-threads – ChrisJ Jul 04 '16 at 15:58

1 Answers1

0

Rather than storing individual variables in session I would store the entire object which contains the state of that calculation. That way as the website is polling for status updates the application can retrieve the current state by retrieving that object from session. It's going to be "in progress," "complete" (the output), or an exception (never happens!)

If you want users to be able to run multiple processes then you could store a Dictionary<guid, YourProcess> and then the client could receive a guid and use it to request the status.

This way the client has a reference to the object which is executing that process, but the thread executing that process doesn't need a reference to the Session or HttpContext. It only needs to know which instance of that class it's operating on, and update it with either progress or the final result.

Scott Hannen
  • 21,450
  • 3
  • 33
  • 44