Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Does Task.Factory.StartNew help or hurt in ASP.Net MVC?

I have an MVC controller action that needs to make several web requests. So in an attempt to free this thread to handle other incoming web requests I wrote something like this: (NOTE: this is an over simplification of the real code)

public async Task<ViewResult> Index()
{
   MyObj o = await Task.Factory.StartNew<MyObj>(() =>
   {
      WebClient c = new WebClient();
      var res1 = c.DownloadString("...");
      var res2 = c.DownloadString("..."); //Not shown but res1 required for this call.
      return new MyObj(res1, res2);
   }
   return View(o);
}

My question is have I made things better or worse by spinning up a new thread to do this work. My intention is to free this .Net thread to handle other incoming requests while the network requests get made. But after looking at it seems to me I'm still making a .Net thread block, just maybe a different one from the thread pool instead of the original, so I'm really no better off. So is my suspicion correct and the above code making things worse?

The benefit of Task.Factory.StartNew() if it worked... is that it simplifies the work inside from having to be done all async. My question though is: Does doing it that way in fact free a thread for handling incoming web requests or is it still tying up the same number of threads from the thread pool?

like image 607
user3766657 Avatar asked Jun 23 '14 08:06

user3766657


People also ask

What does task factory StartNew do?

StartNew(Action<Object>, Object, CancellationToken, TaskCreationOptions, TaskScheduler) Creates and starts a task for the specified action delegate, state, cancellation token, creation options and task scheduler.

What is the difference between task run and task factory StartNew?

Run(action) internally uses the default TaskScheduler , which means it always offloads a task to the thread pool. StartNew(action) , on the other hand, uses the scheduler of the current thread which may not use thread pool at all!


1 Answers

Yes, you are just blocking a different thread now.

If this was good, MVC would just wrap all action methods in a new task automatically.

To unblock threads you need async IO somewhere under the covers. The BCL usually provides this. If it says "async" on the box it usually is async IO.

That said, few web apps have the problem of running out of threads. The thread-pool starts tons of threads if necessary. Very few web apps are limited in throughput by the number of threads available. Do you really need to process 100s of concurrent requests? Can your backend services even handle this load? If any of these questions is answered by "no" you don't need async.

like image 197
usr Avatar answered Sep 18 '22 06:09

usr