ASP.NET MVC AsyncController and IO-bound Requests

I have AsyncController and a home page that asks for a list of friends of users and some kind of database works with them. I applied the asynchronous action method template to any requests that call external web services. Is this an effective way to solve this situation? In times of high volume of requests, I see that IIS is depleted from time to time, and I'm worried that my embedded async magic might somehow participate in this.

My main questions / conversation points:

  • Is it safe to embed an asynchronous IAsyncResult web request inside an Async controller action? Or is it just doubling the load somewhere?
  • Is it efficient to use ThreadPool.RegisterWaitForSingleObject to handle the timing of long web requests or will it consume ThreadPool threads and starve the rest of the application?
  • Would it be more efficient to just execute a synchronous web request inside an Async Controller action?

Code example:

public void IndexAsync() { AsyncManager.OutstandingOperations.Increment(); User.GetFacebookFriends(friends => { AsyncManager.Parameters["friends"] = friends; AsyncManager.OutstandingOperations.Decrement(); }); } public ActionResult IndexCompleted(List<Friend> friends) { return Json(friends); } 

User.GetFacebookFriends(Action<List<Friend>>) as follows:

 void GetFacebookFriends(Action<List<Friend>> continueWith) { var url = new Uri(string.Format("https://graph.facebook.com/etc etc"); HttpWebRequest wc = (HttpWebRequest)HttpWebRequest.Create(url); wc.Method = "GET"; var request = wc.BeginGetResponse(result => QueryResult(result, continueWith), wc); // Async requests ignore the HttpWebRequest Timeout property, so we ask the ThreadPool to register a Wait callback to time out the request if needed ThreadPool.RegisterWaitForSingleObject(request.AsyncWaitHandle, QueryTimeout, wc, TimeSpan.FromSeconds(5), true); } 

QueryTimeout simply aborts the query if it takes more than 5 seconds.

+4
source share
1 answer

The completely asynchronous method that you first describe is best, as it frees TP threads back to the pool for reuse. It is very likely that you are doing other blocking actions elsewhere. What happens in QueryResponse ? Although you get an asynchronous response, are you also reading the response stream asynchronously? If not, do it like this, then TP hunger should be reduced.

+1
source

Source: https://habr.com/ru/post/1398731/


All Articles