4

I was working with Asp MVC 3, and in my application was created Async controller with some methods like:

public void ActionAsync()
{
   AsyncManager.OutstandingOperations.Increment(); 
   AsyncManager.Parameters["someResult"] = GetSomeResult();
   AsyncManager.OutstandingOperations.Decrement();
}

public JsonResult ActionCompleted(SometResultModel someResult)
{
   return Json(someResult, JsonRequestBehavior.AllowGet);
}

And now, when I'm working with MVC4 and Web Api I need to create controller with async actions like in mvc 3. At current time it's looks like:

public Task<HttpResponseMessage> PostActionAsync()
{
     return Task<HttpResponseMessage>.Factory.StartNew( () =>
           {
              var result = GetSomeResult();
              return Request.CreateResponse(HttpStatusCode.Created, result);
           });
}

Is it a good idea to make async actions in web api like this or there some better way is exist?

UPD. Also, if I will use

public async Task<HttpResponseMessage> ActionAsync()
{
   var result = await GetSomeResult();
   return Request.CreateResponse(HttpStatusCode.Created, result);
}

will this full action work in background thread? And how to make my GetSomeResult() function be awaitable? It's return that Task<HttpResponseMessage> is not awaitable.

0

1 Answer 1

2

There is a big difference with your original action in MVC 3 where you are basically releasing the client after the ActionAsync method is invoked (The client thread is released, and it has to call the ActionCompleted action afterward to get the results). If that's what you are looking for, you need to implement async code with tasks on the client side.

Your second version is to make the server code async but the client thread will still wait for a response synchronously. await GetResult will make the server thread to return to the ASP.NET thread pool until the GetResult method returns something, so that thread can be reused with another request. It does not have anything to do with background work. If you want to use a fire and forget approach, you need to use the Task.Factory.StartNew(() => your code) or ThreadPool.QueueUserWorkItem(() => your code)

Sign up to request clarification or add additional context in comments.

4 Comments

can you show me how this Action should look like? I've tried to use this pastebin.com/NeRKfqDp And all my 'POST' queries returns "404"
Factory.StartNew is definitively wrong in that context as you are spinning up an additional thread (Or scheduling some additional work in the thread pool) in addition to the thread currently handling the current request. Is EventModel.PrepareModel returning a Task ?
'EventModel.PrepareModel' is a void function. So, if 'Factory.StartNew' is wrong, what should I use to make async request?
resolved with action like in this topic stackoverflow.com/questions/16282041/…

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.