How do I spawn a task that will run to completion and immediately return to the client?

MatthewMartin

So I'm trying to create a proof of concept for server-side asynch using HTTP 202 codes (where the server accepts the task, immediately returns an endpoint to poll and then creates/updates the resource)

Rick Strahl has a description of how to do this in ordinary ASP.NET. That technique depends on being able to Response.End and then continue to execute code. The Response object doesn't even seem to be available in a Web API controller's context.

If the following worked as planned, it would not block returning the http 202 and still guarantee that the database task will run to completion.

//Insert or Update Asych. 
public Task<HttpResponseMessage> Post(bool asynch, [FromBody]DatedValue value) //Insert Value
{
    Guid key = Guid.NewGuid();

    //Want this to run to completion, even if response associated with parent thread is done.
    Task toWait = Task.Factory.StartNew(() =>
    {
        queue.Add(key, 0);
        DatedValue justCreated = Insert(value);
        queue[key] = justCreated.Id;
    });

    //Return address to resource just created.
    Task<HttpResponseMessage> sender = Task.Factory.StartNew(() =>
    {
        HttpResponseMessage message = Request.CreateResponse(HttpStatusCode.Accepted);
        message.Headers.Location = new Uri("/ValueQueue/" + key);
        return message;
    });

    Task.WaitAll((new[] { toWait, sender }));

    return sender;
}
Badri

Task.WaitAll blocks execution and response is not returned until both the tasks are completed. If you change your code something like below, you should be able to return the response while the task is being run.

public HttpResponseMessage Post(bool asynch, [FromBody]DatedValue value)
{
    Guid key = Guid.NewGuid();

    Task.Factory.StartNew(() =>
    {
        queue.Add(key, 0);
        DatedValue justCreated = Insert(value);
        queue[key] = justCreated.Id;
    });

    HttpResponseMessage message = Request.CreateResponse(HttpStatusCode.Accepted);
    message.Headers.Location = new Uri("/ValueQueue/" + key);
    return message;
}

However, you should be aware of a problem with an approach like this. If you are hosting Web API on IIS, your worker process can get recycled while your task is running. Since you have already returned the response, as far as ASP.NET is concerned, it has completed its work. So, if for some reason IIS decides to recycle the worker process, it will go ahead regardless of where your task is in terms of execution and hence you can end up with corrupt data.

With .NET 4.5.2, you can use QueueBackgroundWorkItem. Read this - http://blogs.msdn.com/b/webdev/archive/2014/06/04/queuebackgroundworkitem-to-reliably-schedule-and-run-long-background-process-in-asp-net.aspx.

Collected from the Internet

Please contact [email protected] to delete if infringement.

edited at
0

Comments

0 comments
Login to comment

Related

From Dev

Run task on background but return response to client in ASP MVC web application

From Dev

How do I get a custom Rake task to run in Sinatra?

From Dev

How to do "redirect_to and return" to exit fully or redirect_to immediately?

From Dev

How do I Set the Planned Completion Date on a Task?

From Dev

How do I check if a specific return type is accepted by the client?

From Dev

How do I change the completion delay in IDLE?

From Dev

How do I spawn a task that will run to completion and immediately return to the client?

From Dev

How do I get the result or return value of a Task?

From Dev

How do I calculate % of task's completion given start date, end date, and TODAY()

From Dev

Run gulp task after completion of other task

From Dev

How do i return a result from a async task

From Dev

How do I Update Run Result on Task Completion?

From Dev

How do I signal completion of my dataflow?

From Dev

How do I schedule a task to run once?

From Dev

How can I run a lambda immediately?

From Dev

Grunt task containing multiple spawn tasks will only run the first task

From Dev

How do i return all the rows of a result set to a client?

From Dev

How do I configure syslinux to boot immediately

From Dev

How do I run commands on suspend/return from suspend?

From Dev

How do I redirect command completion output?

From Dev

Create a scheduled task to run immediately and then hourly

From Dev

How do I run keyframe animations on a div only after the completion of a high resolution image inside that div?

From Dev

How do I return trigger error back to breezejs client side?

From Dev

Task executor will not run next task immediately

From Dev

Ruby on Rails: How do I run an automated rake task on Heroku

From Dev

How do I run a Supervisor task from cron.hourly?

From Dev

Grunt task containing multiple spawn tasks will only run the first task

From Dev

How do I set a task to run at specific time

From Dev

How do I run Minecraft-Console-Client on Ubuntu?

Related Related

  1. 1

    Run task on background but return response to client in ASP MVC web application

  2. 2

    How do I get a custom Rake task to run in Sinatra?

  3. 3

    How to do "redirect_to and return" to exit fully or redirect_to immediately?

  4. 4

    How do I Set the Planned Completion Date on a Task?

  5. 5

    How do I check if a specific return type is accepted by the client?

  6. 6

    How do I change the completion delay in IDLE?

  7. 7

    How do I spawn a task that will run to completion and immediately return to the client?

  8. 8

    How do I get the result or return value of a Task?

  9. 9

    How do I calculate % of task's completion given start date, end date, and TODAY()

  10. 10

    Run gulp task after completion of other task

  11. 11

    How do i return a result from a async task

  12. 12

    How do I Update Run Result on Task Completion?

  13. 13

    How do I signal completion of my dataflow?

  14. 14

    How do I schedule a task to run once?

  15. 15

    How can I run a lambda immediately?

  16. 16

    Grunt task containing multiple spawn tasks will only run the first task

  17. 17

    How do i return all the rows of a result set to a client?

  18. 18

    How do I configure syslinux to boot immediately

  19. 19

    How do I run commands on suspend/return from suspend?

  20. 20

    How do I redirect command completion output?

  21. 21

    Create a scheduled task to run immediately and then hourly

  22. 22

    How do I run keyframe animations on a div only after the completion of a high resolution image inside that div?

  23. 23

    How do I return trigger error back to breezejs client side?

  24. 24

    Task executor will not run next task immediately

  25. 25

    Ruby on Rails: How do I run an automated rake task on Heroku

  26. 26

    How do I run a Supervisor task from cron.hourly?

  27. 27

    Grunt task containing multiple spawn tasks will only run the first task

  28. 28

    How do I set a task to run at specific time

  29. 29

    How do I run Minecraft-Console-Client on Ubuntu?

HotTag

Archive