5

Scenario: I have a web service with a "Delete" ASP.NET Core controller action. The implementation consists of two steps: one cheap after which other operations can already no longer see the deleted data, and a long-running second step which performs the actual deletion.

Is it okay to use Task.Run for the second operation and never await it and so return to the caller very soon? I know that this task could be lost due to application shutdown, but is it even allowed to offload work to the background using Task.Run in ASP.NET Core and never await the resulting task?

D.R.
  • 20,268
  • 21
  • 102
  • 205
  • check out background tasks: https://learn.microsoft.com/en-us/aspnet/core/fundamentals/host/hosted-services?view=aspnetcore-3.1&tabs=visual-studio – Moho Feb 18 '20 at 15:02
  • @Moho Background tasks are used for background services which should run all the time, e.g., a cronjob-like task. They're AFAIK not intended for one-off work from controllers. – D.R. Feb 18 '20 at 15:06
  • How long are we talking about? 10 seconds? 1 hour? a day? – A_kat Feb 18 '20 at 15:10
  • About two to five minutes. But I'm interested in the question in theory as well. – D.R. Feb 18 '20 at 15:13
  • @DR You’re wrong. Check the [Queued background tasks](https://learn.microsoft.com/en-us/aspnet/core/fundamentals/host/hosted-services?view=aspnetcore-3.1&tabs=visual-studio#queued-background-tasks) section. You can also use some background task framework (such as Hangfire) to support scalability of background tasks and retries upon server stops and errors. – Alex Skalozub Feb 18 '20 at 15:16
  • what @AlexSkalozub said; the queue example is well suited for your situation – Moho Feb 18 '20 at 15:24
  • Just remember not to use anything related to the controller or http request itself, because service scope associated with the current request will be gone upon background task execution. – Alex Skalozub Feb 18 '20 at 15:30
  • OK, in that case I will use queued background tasks. Thank you. Still, I'm theoretically interested in the question: is it allowed to just Task.Run() in a controller? – D.R. Feb 18 '20 at 15:39

1 Answers1

5

I know that this task could be lost due to application shutdown, but is it even allowed to offload work to the background using Task.Run in ASP.NET Core and never await the resulting task?

Oh, sure, nothing will prevent this. .NET and ASP.NET allow you to use Task.Run, and the response will be returned to the user without delay (assuming you ignore the task returned from Task.Run).

Is it okay to use Task.Run for the second operation and never await it and so return to the caller very soon?

You say that you're aware that the task could be lost in an app shutdown. And that's true; so it is entirely possible that the second deletion may never happen, and there will be no error or log message informing you of the fact. Furthermore, since the task is ignored, there will be no notification if that task fails, so if there's something wrong with the deletion code, no logs or anything will notify you of regular failures. If you're OK with that, then using fire-and-forget is fine.

On ASP.NET Core, you don't even need Task.Run; you can just call the (asynchronous) method that does the second delete operation and then ignore the task instead of awaiting it.

Simply ignoring tasks will work (with or without Task.Run), but this does have the negative side effect that ASP.NET isn't aware of the offloaded work at all. So I would recommend registering the task and having something delay the app shutdown until the tasks have a chance to complete. With registration, it is still possible to lose tasks, but registering them reduces the chance of losing tasks.

Stephen Cleary
  • 437,863
  • 77
  • 675
  • 810