16

I have the following code:

static async Task Callee() { await Task.Delay(1000); } static async Task Caller() { Callee(); // #1 fire and forget await Callee(); // #2 >1s Task.Run(() => Callee()); // #3 fire and forget await Task.Run(() => Callee()); // #4 >1s Task.Run(async () => await Callee()); // #5 fire and forget await Task.Run(async () => await Callee()); // #6 >1s } static void Main(string[] args) { var stopWatch = new Stopwatch(); stopWatch.Start(); Caller().Wait(); stopWatch.Stop(); Console.WriteLine($"Elapsed: {stopWatch.ElapsedMilliseconds}"); Console.ReadKey(); } 

#1 fires and forgets in the most simple way. #2 simply waits. Interesting stuff begins from #3 on. What's the in-depth logic behind the calls?

I'm aware of using fire'n'forget caveats in ASP.NET as pointed here. I'm asking this, because we're moving our app to service fabric where we no longer can use HostingEnvironment.QueueBackgroundWorkItem(async cancellationToken => await LongMethodAsync()); and the advice is to simply replace it with Task.Run.

I see that Task.Run runs a new thread, what would be the difference between #3 and #5 then?

15
  • 4
    Please define "interesting stuff." Task.Run uses a separate thread. Commented Sep 5, 2017 at 10:54
  • 5
    Possible duplicate of Fire-and-forget with async vs "old async delegate" Commented Sep 5, 2017 at 10:55
  • 4
    Tl;Dr don't use async/await if you want fire and forget. Commented Sep 5, 2017 at 10:56
  • 3
    No it doesn't @Christopher it's asynchronous programming as opposed to multi threaded programming. Aync reuses threads that are idle, multi threaded (Task) created new threads to do processing separate to the main thread. Commented Sep 5, 2017 at 10:58
  • 2
    In words async and await is the difference, you run new async method in separate thread that awaits for something, it doesnt freze your main thread as it is async itself Commented Sep 5, 2017 at 11:09

2 Answers 2

21

I'm asking this, because we're moving our app to service fabric where we no longer can use HostingEnvironment.QueueBackgroundWorkItem(async cancellationToken => await LongMethodAsync()); and the advice is to simply replace it with Task.Run.

That's bad advice. You should use a separate background process separated from your web frontend by a queue.

What's the in-depth logic behind the calls?

  1. Starts the asynchronous method on the current thread. Ignores all results (including exceptions).
  2. Starts the asynchronous method on the current thread. Asynchronously waits for it to complete. This is the standard way of calling asynchronous code.
  3. Starts the asynchronous method on a thread pool thread. Ignores all results (including exceptions).
  4. Starts the asynchronous method on a thread pool thread. Asynchronously waits for it to complete.
  5. Exactly the same as #3.
  6. Exactly the same as #4.
Sign up to request clarification or add additional context in comments.

2 Comments

So is #3 the 'correct' way to do this? Trying to determine based on my question here: stackoverflow.com/questions/67243044/…
@Terry: I don't recommend "fire and forget" at all. If you're on ASP.NET pre-Core and are OK with occasionally losing the "fire and forget" work without any logs or notifications that work has been lost, then I'd say #3 or #5 would be OK.
3

"26. "Fire and Forget" is fine, provided you never actually forget." Maxim 26.

If you do any kind of fire and forget scenario, you have a massive risk of swallowing Exceptions. Swallowing any exception - but especially fatal ones - is a deadly sin of exception handling. All you end up is with a programm in memory that will produce even less understandable and reproduceable Exceptions. So do not ever start. Here is are two nice articles to read on the mater:

http://blogs.msdn.com/b/ericlippert/archive/2008/09/10/vexing-exceptions.aspx http://www.codeproject.com/Articles/9538/Exception-Handling-Best-Practices-in-NET

Full on Threads are notoriously capable of swallowing exceptions. Indeed you have to do work to not swallow them and then check if they had one after they finished. You should have at least some followup task that does logging (and possible exposure) of exceptions. Or you will really regret that "fire and forget".

Hope that helps.

2 Comments

That’s an awesome quote.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.