views:

200

answers:

4

I have an ASP.NET MVC 2 Beta application where I need to block incoming requests for a specific action until I have some data available to return or just release the request after 30 seconds with no new data available.

In order to accomplish this, I'm using AutoResetEvent.WaitOne(30000);

The big issue is that IIS does not seem to be accepting any new request while the thread is blocked at the WaitOne instruction. New requests get hung till the thread releases.

I need to be able to parallelize the requests while still keeping the WaitOne behavior.

+1  A: 

You should not be blocking incoming requests at all. If the data you need are not ready, then return an empty response, or perhaps return an error code.

John Saunders
John, I'm actually working on a Comet-based application, so this behavior is being implemented intentionally to avoid overwhelming the server with tons of sequential requests.
Felipe Lima
What does COMET have to do with blocking threads? Use an async page instead, and your response will be delayed, all without blocking any threads.
John Saunders
Also, "COMET" should be mentioned in your question. Please edit your question to contain more detail.
John Saunders
Do you mean using these AsyncControllers? http://msdn.microsoft.com/en-us/library/ee728598%28VS.100%29.aspx
Felipe Lima
I didn't know about the Async Controllers, but they seem like they should do the job. I meant to use the async capabilities of ASP.NET, and it looks like they will do so. The idea is that no thread is blocked while the long-running operation takes place.
John Saunders
A: 

For a web application, it is more advisable (not a hard rule) to return a message to tell the users to retry again later due to whatever reason you want to call it.

Stalling/blocking the requests by 'waiting' doesn't really help much as the wait is undeterministic, unless of course you have a mechanism to make it so.

I do not know the nature/context/traffic pattern of your website. 30 seconds can be a number that works for you. Perhaps my points above are not really relevant, just my 2 cents.

o.k.w
+2  A: 

Async handlers are what you're looking for. If you're building a comet solution, you may want to check out our .NET implementation of a comet server here, it'll save you some time. If you're wanting to roll your own, you'll definately need to use the async handlers to avoid hitting upper concurrency limits by the time you get past 60 or 70 users, but even with the async handlers, you'll still have to do some fancy footwork. Basically, you're still going to hit some upper limits in the threadpool unless you hand off the requests into a bounded thread pool that can basically manage all the incoming requests for you.

Good luck!

jvenema
Thanks for the information. The WebSync solution seems a great option. However, I am willing to roll my own solution or maybe use some free component, not willing to pay for that! Anyway, thanks for the valuable information!
Felipe Lima
It seems like AsyncControllers are the way to go, since wait handles are not officially supported in this scenario.
Felipe Lima
A: 

Actually, it turns out that this behavior only happens with ASP.NET MVC 2 Beta. I had this working fine with MVC 2 Preview 2 and rolled back to this version to re-test and confirmed that the application worked fine with that version.

Now, the question is: Why am I seeing this different behavior between these two MVC release versions, and what is the correct behavior I should expect to get in this scenario?

Felipe Lima
I strongly suggest you ask Microsoft that question, and that you do so soon enough for them to fix the problem.
John Saunders
I posted an issue at codeplex.com (http://aspnet.codeplex.com/WorkItem/View.aspx?WorkItemId=5034)
Felipe Lima
Blocking on events is generally unsupported in ASP.NET because the framework takes locks on objects on your behalf. For example, if two clients share the same session, their requests will be serialized. This could very easily lead to deadlock issues, which is probably what you're experiencing.Who is responsible for signaling your event, and what does that code look like? Is *that* code able to execute?
Levi