Web API 2 return OK response but continue processing in the background

I used Response.CompleteAsync(); like below. I also added a neat middleware and attribute to indicate no post-request processing.

[SkipMiddlewareAfterwards]
[HttpPost]
[Route("/test")]
public async Task Test()
{
    /*
       let them know you've 202 (Accepted) the request 
       instead of 200 (Ok), because you don't know that yet.
    */
    HttpContext.Response.StatusCode = 202; 
    await HttpContext.Response.CompleteAsync();
    await SomeExpensiveMethod();
    //Don't return, because default middleware will kick in. (e.g. error page middleware)
}

public class SkipMiddlewareAfterwards : ActionFilterAttribute
{
    //ILB
}

public class SomeMiddleware 
{
    private readonly RequestDelegate next;

    public SomeMiddleware(RequestDelegate next)
    {
        this.next = next;
    }

    public async Task Invoke(HttpContext context)
    {
        await next(context);
        if (context.Features.Get<IEndpointFeature>().Endpoint.Metadata
            .Any(m => m is SkipMiddlewareAfterwards)) return;
        //post-request actions here
    }
}

I have managed to solve my problem by running the processing asynchronously by using Task:

    // PUT: api/Afilliate/SaveOrder
    public IHttpActionResult WebHook(ShopifyOrder order)
    {
        // this should process the order asynchronously
        var tasks = new[]
        {
            Task.Run(() => ProcessOrder(order))
        };

        // without the await here, this should be hit before the order processing is complete
        return Ok("ok");
    }

There are a few options to accomplish this:

  1. Let a task runner like Hangfire or Quartz run the actual processing, where your web request just kicks off the task.
  2. Use queues, like RabbitMQ, to run the actual process, and the web request just adds a message to the queue... be careful this one is probably the best but can require some significant know-how to setup.
  3. Though maybe not exactly applicable to your specific situation as you are having another process wait for the request to return... but if you did not, you could use Javascript AJAX kick off the process in the background and maybe you can turn retry off on that request... still that keeps the request going in the background so maybe not exactly your cup of tea.