Call mulitple services or methods asynchronously in ASP.NET MVC controller
I recently had to write some code that reached out to both Google and Bing, performed searches on both, combined and manipulated the results and return the result to the client via JSON.
My problem was that sometimes either of those two services could be slow and there is a possibility that I may need to add additional data sources at a later time. The code originally looked like this:
As you can see, this code would accomplish the goal without a hitch, however if Google took longer than usual, Bing would have to wait for Google to finish. This just creates a bad experience for my users. I needed a way to be able to fire off both of those searches at the same time without blocking one another, however to be of any use to my users, the action would have to wait for both of them to complete before combining the results and return them to the client. This problem would be amplified by adding additional data services (like Yahoo, for example).
Even though I had done this several times in PHP, I had no idea how to accomplish it in C#. I know that AsyncControllers exist and it sounds like they rock, but what if I wanted to keep this all in the same controller as other related code?
I did some digging and found nothing, so I turned to a developers best friend – StackOverflow. I posted a question asking how to accomplish this and got back a few great answers.
This is what I decided on, and it works great:
You can create as many Task’s as you need, and then start each of them with the Start() method. Then using the Task.WaitAll() method, you instruct your program to wait until all of those Task’s have completed before continuing to the next line of code.
You can also specify a timeout as the second parameter of Task.WaitAll that will prevent your Task’s from running indefinitely, which is definitely helpful for Ajax requests when the client is waiting on some response.
ASP.NET MVC 3, Razor, & RenderAction causing server to hang and crash
I am working on a new project and decided to use the awesome new ASP.NET MVC3 (RC2) framework with Razor templating. Razor is awesome. Its clean and gets the job done nicely, but when I tried to render an action into my view, all hell broke loose.
This is what my controller looked like:
public class MyController : BaseController
{
public ActionResult Index()
{
return View();
}
public ActionResult ProductDetails(String id)
{
return View();
}
}
}
And in my view I had this:
@{Html.RenderAction("ProductDetails", "My", new { id = ViewBag.Id});}
But whenever I would navigate to a URL that corresponded to a view containing this RenderAction snippet, the browser would hang and the server would stop responding completely. I double checked my code, I restarted the server, I restarted the browser, I restarted the IDE. I tried everything, but no luck.
Problem Solved
It has something to do with Razor’s layouts and what I believe may be an infinite loop. I think what is happening is that the action being rendered via RenderAction is also trying to load the base template that is found in _ViewStart.cshtml which is rendering the body which is calling RenderAction… and this continues infinitely.
The solution is to either tell your view to NOT use a layout or to change your action from ActionResult to PartialViewResult. I chose the latter and once I restarted the server again, everything started working correctly.