Search code examples
asp.netiisinternet-explorersessionend

Session_End called multiple times in the middle of a session


Am I using Session_End incorrectly?

In my application, I have a cache to speed up page loads, it works quite well. Recently, someone suggested to me that I was leaking memory by never emptying it out, and to implement a method on Session_End that will clear out any cache entries associated with that session id.

Occasionally though I started seeing anomalous behaviour. When loading a page, very rarely I would see an empty page, showing an exception due the the cache for that page being empty. I put a debugger breakpoint in the cache access and the session_end methods, hoping to catch it the next time it ocurred.

The next time it happened I was quite surprised at what was actually happening. My browser was left open but idle for a long time, so I'm guessing it had a stale session cookie. It hits the server for the page, which puts a copy of the page into the cache. While the page is still loading, Session_End is called instantly, which deletes it out of the cache. If I reload the browser, Session_End keeps getting called, agressively trying to close my session that the poor browser keeps requesting.

So I suppose my real questions are:

  • Why isn't the browser getting a new session cookie if the old one is that anathemic to IIS?
  • Is Session_End simply not designed to be used in this way?
  • Is there a better way to do what I'm trying to do?

@Sosh - my global.asax.cs:

    protected void Session_End(Object sender, EventArgs e)
    {
        //clean up object cache on session expiry
        string sessionID = this.Session.SessionID;

        foreach (string key in Global.DataGroups.Keys)
        {
            if (key.EndsWith(sessionID))
            {
                Global.DataGroups.Remove(key);
            }
        }
    }

Solution

  • Yes there is a better way. Use the built-in Cache object. It seems like you are re-inventing the wheel... Cache will be much more reliable. Just set the expiration time to match the session timeout. If you have to reload the cache every 20 minutes, so what?

    In general, I've found that Session_End is a bit akin to Application_End in that you can never quite be sure when it's going to be called and it's sometimes counter-intuitive.