Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

ASP.NET Multithreading Web Requests

I'm building a page in my ASP.NET solution that retrieves most of its data from a 3rd Party API Service.

The page itself will need to make approximately 5 individual different calls to the API to populate all of its controls, as each Web Request to the API brings back different sets of Data.

I would like to deal with each separate Web request i make on a new thread, simultaneously so that load time is reduced.

Each request I'm making looks like this :-

WebRequest request = WebRequest.Create(requestUrl);

string response = new StreamReader(request.GetResponse().GetResponseStream()).ReadToEnd();

return new JsonSerializer().Deserialize<OccupationSearch>(new JsonTextReader(new StringReader(response)));

Firstly, should i be attempting this? i.e, is it safe? and will it enhance performance by multi-threading this out.

Secondly, what is the best way to go about doing this? There's many different ways to multi-thread systems, but which will suit this task best?

like image 281
Derek Avatar asked May 28 '14 13:05

Derek


People also ask

What is multi-threading in ASP NET?

Multi-threading in ASP.NET. Inside the ASP.NET Worker Process, there are two thread pools. The worker thread pool handles all incoming requests and the I/O Thread pool handles the I/O (accessing the file system, web services and databases, etc.).

What is thread pool in ASP NET?

Every ASP.NET web application has its own pool of threads that is used for serving requests. Limitations of this pool can be configured on web server level as well as application level.

How can I increase the number of threads in ASP NET?

The fact is that ASP.NET installs with a fixed, default number of threads to play with: the 1.x Framework defaults to just 20 worker threads (per CPU) and 20 I/O threads (per CPU). The 2.0 Framework defaults to 100 threads in each pool, per CPU. Now this can be increased by adding some new settings to the machine.config file.

What is the use of process request in ASP NET?

The ProcessRequest method is passed an HttpContext Object containing all the data ASP.NET has collected about the request, as well as exposing the Session, Server, Request and Response objects that you are used to working with in page requests. There are 2 ways to build them.


2 Answers

Multi-threading is the right choice, but I would call it doing stuff asynchronously.

Anyway, you should know that multi-threading works different in IIS.

IIS worker process will finish a request once all child threads end, and this is a big problem, because you don't want to hold a worker process for a long time but re-use it for other requests. Actually it's a thread pool.

This is why ASP.NET offers its own approach to implement asynchronity and if you use the right approach, IIS will be able to process more requests at once because asynchronous work will be executed outside IIS process model.

I would suggest you to read more about ASP.NET async:

  • http://www.hanselman.com/blog/TheMagicOfUsingAsynchronousMethodsInASPNET45PlusAnImportantGotcha.aspx

  • http://blogs.msdn.com/b/tmarq/archive/2010/04/14/performing-asynchronous-work-or-tasks-in-asp-net-applications.aspx

Conclusion: use asynchronous work and this will make a more efficient use of server resources, but first learn more about how to do it in the right way!

like image 150
Matías Fidemraizer Avatar answered Oct 20 '22 06:10

Matías Fidemraizer


Multithreading is not recommended on ASP.NET; because ASP.NET/IIS does its own multithreading, and any multithreading you do will interfere with those heuristics.

What you really want is concurrency, more specifically asynchronous concurrency since your operations are I/O-bound.

The best approach is to use HttpClient with the Task-based Asynchronous Pattern:

public async Task<OccupationSearch> GetOccupationAsync(string requestUrl)
{
  // You can also reuse HttpClient instances instead of creating a new one each time
  using (var client = new HttpClient())
  {
    var response = client.GetStringAsync(requestUrl);
    return new JsonSerializer().Deserialize<OccupationSearch>(new JsonTextReader(new StringReader(response)));
  }
}

This is asynchronous, and you can easily make it concurent by using Task.WhenAll:

List<string> urls = ...;
OccupationSearch[] results = await Task.WhenAll(urls.Select(GetOccupationAsync));
like image 23
Stephen Cleary Avatar answered Oct 20 '22 06:10

Stephen Cleary