Reputation: 12367
In my ASP.NET MVC web application I'm consuming a web service that sometimes might take long to respond. In this case the user might want to cancel the request and be able to make other requests. But as the server is still busy processing the previous request, the user has to wait until that one is complete. For that reason I decided to make some action methods that perform intensive IO job async, hoping the main thread won't be blocked. But that doesn't help. Here's my method:
1:public class TestController:AsyncController{
2: public async Task<ActionResult> GetString(){
3:
4: string data=await Task<string>.Factory.StartNew(()=>{
5: return service.GetDataAsString("name");
6: });
7: return View(data);
8: }
9:}
The line 7 won't be executed unless the service returns the expected string , so still blocking remains. What do I have to do to make the whole action to take place in a separate thread? Do I have to go old fashion? Aren't async methods meant for this kind of things?
Upvotes: 1
Views: 547
Reputation: 456497
Aren't async methods meant for this kind of things?
No, async
doesn't change the HTTP protocol. You still only have one response per request, and that response can only be sent once.
async
will free up the calling thread, but on ASP.NET this just means that the thread is returned to the thread pool and is able to handle other requests; it doesn't send an HTTP response to the user. In your particular case, the code is first taking a thread from the thread pool (StartNew
) in order to free up a thread from the thread pool (await
), which is pointless.
There are a few solutions which should work. You could remove session state or replace this call with a SignalR hub (permitting other user requests while the old one finishes), or you can do this AJAX-style - preferably with a reliable queue connected to an independent worker process.
Upvotes: 2