Why/when are session writes vulnerable to thread termination?

THE CODE:

Session["foo"] = "bar";  
Response.Redirect("foo.aspx");

THE PROBLEM:

When foo.aspx reads “foo” from the session, it’s not there. The session is there, but there’s no value for “foo”.

I’ve observed this intermittently in our production environment. But I don’t mean here to ask a question about Response.Redirect().

THE EXPLANATION:

Bertrand Le Roy explains (the bolding is mine):

Now, what Redirect does is to send a
special header to the client so that
it asks the server for a different
page than the one it was waiting for.
Server-side, after sending this
header, Redirect ends the response.
This is a very violent thing to do.
Response.End actually stops the
execution of the page wherever it is
using a ThreadAbortException. What
happens really here is that the
session token gets lost in the battle.

My takeaway there is that Response.Redirect() can be heavy-handed with ending threads. And that can threaten my session writes if they occur too near that heavy-handedness.

THE QUESTION:

What about ASP.NET session management makes it so vulnerable to this? The Response.Redirect() line of code doesn’t begin its execution until the session write line is “finished” — how can it be such a threat to my session write?

What about the session write doesn’t “finish” before the next line of code executes? Are there other scenarios in which session writes are similarly (as though they never occurred) lost?

Answers:

Thank you for visiting the Q&A section on Magenaut. Please note that all the answers may not help you solve the issue immediately. So please treat them as advisements. If you found the post helpful (or not), leave a comment & I’ll get back to you as soon as possible.

Method 1

I’m not familiar enough with the internals of session writing, but I imagine it has some complexities, as it relies on translating the browser session cookies into a server identification. Additionally, ThreadAbortExceptions do have special considerations in the runtime, which may play in here, I’m not sure.

In any case, Response.Redirect() has an overload that takes a boolean parameter that lets you specify whether you want to end the thread or not.

Response.Redirect(string url,  bool endResponse);

If you call it with endResponse set to “false”, it will gracefully finish, rather than calling Thread.Abort() internally. However, this means it will also execute any code left in the page lifecycle before finishing up.

A good compromise is to call Response.Redirect(url, false) followed by Application.CompleteRequest(). This will allow your redirect to happen but also gracefully shut down the current execution context with a minimal amount of additional lifecycle processing.

Method 2

After testing several alternatives (Response.Redirect(…, false), Server.Transfer(), and other “solutions” I can’t now recall), we’ve found only one reliable answer to this problem.

Moving our session state from InProc to SqlServer effectively eradicated this behavior from our systems, leaving Response.Redirect(…) completely reliable. If further testing shows otherwise, I’ll report here, but I say, to make this stop happening in your environment: move your session state into SqlServer (or is “out of InProc” good enough? I’m not sure).

Method 3

Application pool recycle can cause your session to go away. You can configure the app pool to recycle at fixed times (recommended, and at night or during low-usage periods) or increase the timeout period of your app pool recycle.


All methods was sourced from stackoverflow.com or stackexchange.com, is licensed under cc by-sa 2.5, cc by-sa 3.0 and cc by-sa 4.0

0 0 votes
Article Rating
Subscribe
Notify of
guest

0 Comments
Oldest
Newest Most Voted
Inline Feedbacks
View all comments
0
Would love your thoughts, please comment.x
()
x