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?
Task.Runuses a separate thread.async/awaitif you want fire and forget.Task) created new threads to do processing separate to the main thread.