Question

I check a session object and if it does exist then call another method which would use that object indirectly. Although the second method would access this object in a few nanoseconds I was thinking of a situation when the object exactly expires between two calls. Does Session object extends its lifetime on every read access from code for preventing such a problem ? If not how to solve the problem ?

If you are going to say why I don't pass the retrieved object from first method to second one, this is because I pass the ASP.NET Page object which carries many other parameters inside it to second method and if I try to pass each of them separately, there would be many parameters while I just pass one Page object now.

Was it helpful?

Solution

Don't worry, this won't happen

If I understand your situation it works sort of this way:

  1. Access a certain page
  2. If session is active it immediately redirects to the second page or executes a certain method on the first page.
  3. Second page/method uses session

You're afraid that session will expire between execution of the first and second method/page.

Basically this is impossible since your session timer was reset when just before the first page starts processing. So if the first page had active session then your second page/method will have it as well (as long as processing finishes before 20 minutes - default session timeout duration).

How is Session processed

Session is processed by means of an HTTP Module that runs on every request and before page starts processing. This explains the behaviour. If you're not familiar with HTTP Modules, then I suggest you read a bit about IHttpModule interface.

OTHER TIPS

It's quite difficult to understand your question, IMHO, but I will try.

From what I understand, you're doing something like:

string helloWorld = string.Empty;
if (this.Session["myObject"] == null)
{
    // The object was removed from the session or the session expired.
    helloWorld = this.CreateNewMyObject();
}
else
{
    // Session still exists.
    helloWorld = this.Session["myObject"].ToString(); // <- What if the session expired just now?
}

or

// What if the session existed here...
if (this.Session["myObject"] == null)
{
    this.Session["myObject"] = this.CreateNewMyObject();
}

// ... but expired just there?
string helloWorld = this.Session["myObject"].ToString();

I thought that Session object is managed by the same thread as the page request, which would mean that it is safe to check if object exists, than use it without a try/catch.

I were wrong:

For Cache objects you have to be aware of the fact that you’re dealing essentially with an object accessed across multiple threads

Source: ASP.NET Cache and Session State Storage

I were also wrong about not reading to carefully the answer by Robert Koritnik, which, in fact, clearly answers the question.

In fact, you are warned about the fact that an object might be removed during page request. But since Session lifespan relies on page requests, it would mean that you must take in account the removal of session variables only if your request takes longer than the session timeout (see How is Session processed in the answer by Robert Koritnik).

Of course, such situation is very rare. But if in your case, you are pretty sure that the page request can take longer than 20 minutes (default session timeout), than yes, you must take in account that an object may be removed after you've checked if it exists, but before you really use it.

In this situation, you can obviously increment the session timeout, or use try/catch when accessing the session objects. But IMHO, if the page request takes dozens of minutes, you must consider other alternatives, as Windows services, to do the work.

I'm having difficulties understanding what the problem here is but let me try it again referring to thread safety.

Thread safety issue

If this is a thread safety issue, you can always issue a lock when creating a certain session object so other parallel requests won't run into a problem by double creating your object.

if (obj == null)
{
    lock (objLock)
    {
        if (obj == null)
        {
            obj = GenerateYourObject();
        }
    }
}

Check lock documentation on MSDN if you've never used it before. And don't forget to check other web resources as well.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top