You might find yourself wanting to start an async Task either through Task.Run(() => ...) or something like Task DoSomethingAsync() or Task.Delay() where you don't want to await the completion of the task. You just want the step to complete and the task to continue running in the background. But it wont work.

In my situation I wanted to hit a URL 10 minutes after the Octopus deployment was completed and I didn't want the deployment to "hang" for 10 minutes seemingly still deploying.

I tried several different methods, like mentioned in the beginning, but the tasks were never run to completion.

I'm pretty sure I know why this happens, although I haven't actually confirmed it. I'm assuming Octopus fires up a new ScriptCS process with our C# script as the input. When our script reaches the end, i.e. not awaiting any tasks etc., then the process exits and any unfinished tasks goes with it.

Alternative solution using Azure

I ended up with sort of an alternative solution using Azure Functions and Queue Storage which is free (or close to) for most solutions that don't require a lot of throughput.

It's pretty simple and in short it consists of an HTTP endpoint which adds (delayed) a message to the queue, and then a function with a queue trigger which executes the message. In Octopus I then just call the HTTP endpoint to trigger a delayed action and that's that.

I'll leave it at that and leave the details of the Azure stuff to a future blog post.