Last post Dec 10, 2009 09:20 AM by levib
Dec 08, 2009 09:03 AM|liangxingyuan|LINK
1.I have a asp.net page, using the mvc 1.0.
2.I have make two ajax call to the same method of mvc controller.
In this method, i just thread.sleep(6000);
3.After page is being request and load, the two ajax call happen in the same time to same method.
Expect: Two ajax call return in already same time, each of time should just cost near 6 seconds.
Actual: Two ajax call return one by one depending on the ajax call seq,
And the first ajax call cost near 6 seconds, but the next ajax call cost near 12(6 * 2)secondes.
Seems the two ajax call is excuted in a seq not concurrently.
Do anyone know what's the problem???
I am so so so confused.!!!
"ASP.NET MVC 1.0"
Dec 08, 2009 09:17 AM|thinkrajesh|LINK
Need some clarification..
How and in what way are you invoking these ajax calls?
Asp.net MVC Ajax
Dec 08, 2009 12:55 PM|liangxingyuan|LINK
I also had the same concern as your before.
I have try different ajax lib.
One is ExtJs, the second is JQuery($.Post()).
I saw two requests have been actually sent out at the same time via firebug in firefox.
Moreover, if i test different methods in the same controller, i got the same result that seems can't be concurrent.
So i am confused.
Anyone who can help me or who can try a test as my clarfication
Thanks a lot!
Dec 08, 2009 03:36 PM|bradwils|LINK
Because requests in MVC have access to session state, the requests are serialized to prevent corruption to session state.
If you have long-running actions, you should make them async.
Dec 08, 2009 07:56 PM|ricka6|LINK
If you have multiple parallel calls to make, that's a bigger bonus for using the new MVC 2 Async controller. See my MSDN article
Using an Asynchronous Controller in ASP.NET MVC and my blog entry
Should my database calls be Asynchronous?
Dec 09, 2009 08:06 AM|liangxingyuan|LINK
Did you mean this strategy is to prevent from two thread accessing the sessoin state in the same time?
Becuase session state is not thread-safe.
Dec 09, 2009 08:21 AM|liangxingyuan|LINK
Thanks a lot!!
I saw the frist link: Using an Async controller. And the second link doesn' t work
It seems the controller use a background thread to do the real work, so it can return my call suddently.
I have question for this:
Why we can't have mutilple control instance for one session when call happening?
And the parallel call and async call is a different issue.
Certainly, We can use the async call to sovle the parallel call, but it just look like we have solve but not actully in the strategy.
So can we allow the parallel call to the same page for the same controller in current mvc framework?
Dec 09, 2009 12:36 PM|liangxingyuan|LINK
Maybe i found the where the problem is.
Access to ASP.NET session state is exclusive per session, which means that if two different users make concurrent requests, access to each separate session is granted concurrently. However, if two concurrent requests are made for the same session (by using
the same SessionID value), the first request gets exclusive access to the session information.
The second request executes only after the first request is finished. (The second session can also get access if the exclusive lock on the information is freed because the first request exceeds the lock time-out.) If the
EnableSessionState value in the
@ Page directive is set to ReadOnly, a request for the read-only session information does not result in an exclusive lock on the session data. However, read-only requests for session data might still have
to wait for a lock set by a read-write request for session data to clear.
Dec 09, 2009 04:22 PM|bradwils|LINK
It's about predictability rather than thread safety.
If two requests for the same user, which both need read/write access to that user's session state, were allowed to run concurrently, then they could end up with session state being in an unpredictable state, because both requests are reading and writing
to it. By serializing the requests per-user, this situation doesn't come into play.
When you use async action, then your request ends up with basically 3 phases: the beginning, where you schedule all the background work; the time when the background work is going on; and the end, when you collect all the results and formulate the response.
The middle bit is where most of your time should be spent, and during that middle bit, the session is not locked, so concurrent connections from the same user will be allowed to execute while the work is going on in the background.
Dec 10, 2009 12:13 AM|liangxingyuan|LINK
So when in the background work, the thread can't access the session because it doesn't exist.
And this protect us for predictability sesseion.
Dec 10, 2009 09:13 AM|levib|LINK
I'm afraid there's been a bit of a miscommunication here. Since the MvcHandler is marked as
IRequiresSessionState, the Session lock is taken around each MVC request. Consider "request" the time period from when the first byte is sent from the client to the server to when the last byte is sent from the server to the client. This affects both
regular MVC controllers and async controllers. So even though an AsyncController may have yielded its thread back to ASP.NET, the Session lock is still active.
We have a work item to make MVC smarter so that the Session lock isn't taken if a controller doesn't need it, but this isn't likely to make it into MVC 2.
Dec 10, 2009 09:20 AM|levib|LINK
By the way - there are workarounds to this issue. Essentially this involves you writing your own IRouteHandler and IHandler. Your IRouteHandler.GetHttpHandler() method returns an instance of your custom IHttpHandler, and your IHttpHandler.ProcessRequest()
method just calls the existing MvcHandler.ProcessRequest(). This way, your custom IHttpHandler wraps MvcHandler but doesn't expose the same
IRequiresSessionState interface it does. See: