Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Return HTTP Response immediately in ASP.NET Web API

I am working on a WebAPI2 project doing some data collection, and I am trying to figure out how I can reduce the response time of my API methods.

I have a JavaScript function that posts information to my api. My API receives this information, inserts it in to the database, and then returns an HTTP Accepted.

Lets say there is a 5 second wait time for the data processing to be completed

// POST api/<controller>
public HttpResponseMessage Post([FromBody]string value)
{
  //This represents 5000 milliseconds of work
  System.Threading.Thread.Sleep(5000);

  return new HttpResponseMessage(HttpStatusCode.Accepted);

}

This means, when my JavaScript function calls the Post Method, it waits 5 seconds for the response.

Is there a way I can immediately return a response of HTTP Accepted, and then continue processing my data?

Update solution from lilo.jacob

Ok, I've updated my method with the threading solution found below. Here is the new code

// POST api/<controller>
public HttpResponseMessage Post([FromBody]string value)
{
  new System.Threading.Tasks.Task(() =>
    {
      //This represents 5000 milliseconds of work
      System.Threading.Thread.Sleep(5000);
    }).Start();

  return new HttpResponseMessage(HttpStatusCode.Accepted);
}

The response is returned almost immediately, which is exactly what I was looking for. Here are some results from Fiddler showing the change in response time Response time in Fiddler

The first response show the lag with WebAPI on startup, requests 4,5, and 7, are using threading and fired immediately after each other. Response 11 shows the same request without threading enabled, notice the 5 second delay.

Very cool, clean, and lean solution to the problem.

like image 428
Cubix Avatar asked May 13 '14 16:05

Cubix


People also ask

How do I return a response in Web API?

Depending on which of these is returned, Web API uses a different mechanism to create the HTTP response. Convert directly to an HTTP response message. Call ExecuteAsync to create an HttpResponseMessage, then convert to an HTTP response message. Write the serialized return value into the response body; return 200 (OK).

Why should I use IHttpActionResult instead of HttpResponseMessage?

We have the following benefits of using IHttpActionResult over HttpResponseMessage : By using the IHttpActionResult we are only concentrating on the data to be send not on the status code. So here the code will be cleaner and very easy to maintain. Unit testing of the implemented controller method will be easier.

How do I return IHttpActionResult in Web API?

IHttpActionResult contains a single method, ExecuteAsync, which asynchronously creates an HttpResponseMessage instance. If a controller action returns an IHttpActionResult, Web API calls the ExecuteAsync method to create an HttpResponseMessage. Then it converts the HttpResponseMessage into an HTTP response message.

What is return OK in Web API?

The ok read-only property of the Response interface contains a Boolean stating whether the response was successful (status in the range 200-299) or not.


2 Answers

You can try execute your "expensive" code in separate thread.

It will be something like this:

// POST api/<controller>
public HttpResponseMessage Post([FromBody]string value)
{
    new System.Threading.Tasks.Task(() =>
    {
        //insert to db code;
    }).Start();

    return new HttpResponseMessage(HttpStatusCode.OK);

}
like image 101
lilo.jacob Avatar answered Sep 21 '22 03:09

lilo.jacob


I believe @lilo,jacob's answer is not a reliable solution if the background task takes long-time. It may never complete and you lost data. Read this answer please: https://stackoverflow.com/a/25275835/538387

like image 33
Tohid Avatar answered Sep 21 '22 03:09

Tohid