0

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.

Xaqron
  • 29,931
  • 42
  • 140
  • 205
  • 1
    can you rephrase your question and add some code to it? Two of us tried to answer it, both having difficulty understanding the problem... Is it maybe a thread safety issue? – Robert Koritnik Nov 29 '10 at 16:03

3 Answers3

1

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.

Robert Koritnik
  • 103,639
  • 52
  • 277
  • 404
  • This is not my case. I process a session in one round-trip, I mean there's no redirection. That's why I told a few nanoseconds. – Xaqron Nov 29 '10 at 14:41
  • @Xacron: So how do you get to the second page? `Server.Transfer()` then? But even if you're making a call to a different method on the same page, my last part of the answer should explain why you shouldn't worry. Session timeout timer has been reset before your page started processing, so it shouldn't happen at all. – Robert Koritnik Nov 29 '10 at 14:46
  • very close. If the session object collection is remain accessible for an entire request lifetime so my scenario never happens (no worry) since the response for the request is not produced yet. Is it what you say ? – Xaqron Nov 30 '10 at 11:16
  • @Xaqron: Exactly since session timeout timer was reset before your page started processing meaning that session will be present for the next 20 minutes (if using default)! Unless of course your request lasts for more than session timeout (default is 20 minutes) in which case your web application design is wrong. Requests should respond as quick as possible. As @MainMa suggested you should transfer long running processing to other processes. Don't do them within your web request. – Robert Koritnik Nov 30 '10 at 12:03
0

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.

Arseni Mourzenko
  • 50,338
  • 35
  • 112
  • 199
  • It's something like what you wrote (a few more code) but theoretically it's possible for session object to be swapped by framework between two calls. Consider a page with thousands visits. – Xaqron Nov 29 '10 at 14:57
0

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.

Robert Koritnik
  • 103,639
  • 52
  • 277
  • 404
  • This is not about thread-safety. Simply, what if a session object expires between two calls to retrieve it ? As we know a session object is held in server memory and ASP.NET (internally uses a hash table) is responsible for its life-cycle (we don't know when EXACTLY it would be removed from memory). We access the value of it via a key i.e Session("Test") so it's possible for Session("Test") to return null (Session expired) or an object. By default a session lives for 20 minutes. Theoretically it is possible for the Session("Test") to be expired between two calls in the same method... – Xaqron Nov 30 '10 at 11:09
  • @Xaqron: Only when these two calls are apart (in time perspective) by more than 20 minutes. But even then I'm not 100% sure that session would be expired, since both calls are part of the same request. A very long one though... – Robert Koritnik Nov 30 '10 at 13:45