5

I have this [HttpPost] action method:

[HttpPost]
public ActionResult AddReview(Review review)
{
   repository.Add(review);
   repository.Save();
   repository.UpdateSystemScoring(review.Id); // call SPROC with new Review ID.
   return View("Success", review);
}

So, basically a user clicks a button, i add it to my database (via Entity Framework 4.0), save changes, and then i call a stored procedure with the identity field, which is that second last line of code.

This needs to be done after the review is saved (as the identity field is only created once Save is called, and EF persists the changes), and it is a system-wide calculation.

From the user point of view, he/she doesn't/shouldn't care that this calculation is happening.

This procedure can take anywhere from 0-20 seconds. It does not return anything.

Is this a candidate for an asynchronous controller?

Is there a way i can add the Review, and let another asynchronous controller handle the long-running SPROC call, so the user can be taken to the Success page immediately?

I must admit (partially ashamed of this): this is a rewrite of an existing system, and in the original system (ASP.NET Web Forms), i fired off another thread in order to achieve the above task - which is why i was wondering if the same principal can be applied to ASP.NET MVC 3.

I always try and avoid multi-threading in ASP.NET but user experience is the #1 priority, and i do not want the page timing out.

So - is this possible? Also happy to hear any other ideas. Also - i can't use triggers here, don't really want to go into too much detail why - but i can't.

4 Answers 4

4

I would fire a new thread (not from the thread pool) to perform this task and return immediately especially if you don't care about the results. Asynchronous controllers are useful in situations where most of the time is spent waiting for some other system to complete the task and you once this system completes the task your application is signaled to process the result. During the execution of the task no threads are consumed from your application. So in your scenario this task could be performed by SQL Server using the async versions of the BeginRead methods in ADO.NET. You could use this if you need the results back. If you don't firing a new thread would work just fine as before.

Sign up to request clarification or add additional context in comments.

5 Comments

Really? When i originally proposed doing this (in the original version of the system), i got crucified by John Saunders and was ask to "read up on ASP.NET". And yes - i don't care about the result. The SPROC does not return anything - just makes changes to the data. So - you'd recommend firing a thread as before?
And what do you mean "not from the the thread pool?". Previously i was just doing new Thread(), set the method, pass the array params, etc.
@RPM1984, ASP.NET uses a thread pool to service requests. There are preinitialized threads in this pool and when a request comes in ASP.NET draws a thread from this pool. It doesn't create a new thread because this might be expensive. Doing new Thread() is ok because you are creating a new thread. Also could you point to the post where you got crucified by John Saunders?
Okay cool, guess i'll go with that then. And here is the post i was referring to: stackoverflow.com/questions/3473395/… Obviously the word "crucified" is an exagerration, but mainly i was surprised that a person of his stature/rep would state "you can't do this kind of thing in ASP.NET"
@RPM1984, I think that what John meant was that you cannot any longer rely on any of the Http Context properties (Request, Response, Session, ...) in the worker method that gets executed on a new thread. But as long as you are simply calling an SPROC using ADO.NET it is fine.
1

I think asynchronous controllers are more for things where the request may take a long time to return a response, but the main thread would spend most of that time waiting for another thread/process. This is mostly useful for ajax calls rather than main page load, when it is acceptable to just show a progress indicator until the response is returned.

I use a separate queueing system for this type of task, which is more robust and easier to work with but does take a bit more work to set up. If you really need to do it within the ASP.net process, a separate request is probably the best option, though there is some potential for the task not to run - for example I'm not sure what happens if the connection drops or the app pool recycles while an async task is running.

1 Comment

Yeah i didn't want to have to touch the architecture of the system, which is why im trying to avoid a queueing system (wcf service, sql server broker, etc).
1

Since the scoring system takes so long to run I would recommend using a scheduled task in SQL Server or Windows to update the scores every x amount of minutes. Since the user doesn't know about the request it don't matter to run immediately.

You could add the ID's to a queue and process the queue every 30 minutes.

Otherwise if there is a reason this needs to be run immediately you could do an asyc call or see if you could trim some fat of the stored proc.

Comments

1

I have a very similar system that I wrote. Instead of doing things synchronously we do everything asynchronous using queues.

Action -> causes javascript request to web server
   |
Web server puts notification on queue
   |
Worker picks up message from queue and does point calculation
   |
At some point in future user sees points adjusted

This allows us to be able to handle large amounts of user load and not need to worry about this having an adverse affect on our calculation engine. This also means that we can add more workers to handle larger load when we have large load and can remove workers when we don't have a large load.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.