-2

I have an async method DoSomething() and inside the DoSomething() I am calling another method "SaveINSQLDB()" as below.

private static async Task Dosomething()
{
    my few lines of code....

    SaveINSQLDB()... // I don't want wait for its response to execute further
                     // (fire and forget case).
    my few lines of code
}

I can do with any of the below approaches, Please suggest me the optimal one (and please state why?).

Case 1.

Task.Run(() => SaveINSQLDB(arg1, arg2)); 

I can make SaveINSQLDB() a simple static method.

Case 2.

await Task.Run(async () =>
                          {
                             await SaveINSQLDB(arg1, arg2);
                          }); 

I can make SaveINSQLDB() an static async method.

In My opinion, Case1 is better.

Uwe Keim
  • 39,551
  • 56
  • 175
  • 291
Bikram
  • 483
  • 6
  • 16
  • Why do you think `Case1` is better? They both probably compile to IL in the same fashion. – Stuart.Sklinar Sep 18 '19 at 10:58
  • 2
    *Case 2. `await Task.Run(async () => { await SaveINSQLDB(arg1, arg2); });`* hmmm case 2 is wating for the results so it's not fire and forget – Selvin Sep 18 '19 at 10:59
  • @Selvin case 1 won't even fire. You still need to run `task.Wait()` or something. Otherwise, it is just wrapper into Task – OlegI Sep 18 '19 at 11:06
  • Case one is the correct solution, trigger a new task but don't wait for it's result – Muaddib Sep 18 '19 at 11:13
  • @Olegl *case 1 won't even fire. You still need to run task.Wait() or something. Otherwise, it is just wrapper into Task* [are you sure?](https://dotnetfiddle.net/jUmY4b) ... seems like you read too much "Task is not a Thread" ... in case of `Task.Run` we can say Task is kind of Thread as *Task.Run - Queues the specified work to run on the ThreadPool* – Selvin Sep 18 '19 at 11:13
  • @Olegl Task.Run() works same as Task.Factory.StartNew(); – Bikram Sep 18 '19 at 11:59
  • Remember that "fire and forget" doesn't only mean "don't wait for it", but it also means "I don't care if this even succeeds". There is a good read about it here, with options on how to handle it: [Fire and Forget on ASP.NET](https://blog.stephencleary.com/2014/06/fire-and-forget-on-asp-net.html) – Gabriel Luci Sep 18 '19 at 12:27

2 Answers2

1

Case 1 will start a Task and execute the remainder of Dosomething() immediately afterwards.

Case 2 will start a Task and wait for it to complete before executing the remainder of Dosomething().

So if you want to call SaveINSQLDB without blocking and waiting for it to complete, you should go with the first option. You may want to catch exceptions and do some logging in the action that you pass to Task.Run though.

mm8
  • 163,881
  • 10
  • 57
  • 88
0

I would go with Case 1 if it was me. It is clear that it is "fire and forget" in that case.

In case 2 the presence of the await keyword could make someone reading it think it was going to await the response if they misread the await as being for the top level call not within the fire-and-forget process.

You're not going to do anything with the awaited reply so there's no need to await it.

Edit: Sorry I missed the very first await in case 2. As Selvin pointed out in the comment to my answer case 2 is not fire and forget as it is awaiting the reply. Case 1 is the way to go if you want fire-and-forget.

Example from MS docs does it akin to case1:

var t = Task.Run(() => {  Console.WriteLine("Task thread ID: {0}",
                                   Thread.CurrentThread.ManagedThreadId);
                             } );
MDBarbier
  • 379
  • 3
  • 12
  • 1
    *In case 2 the presence of the await keyword could make someone reading it think it was going to await the response if they misread the await as being for the top level call not within the fire-and-forget process.* **What? there are 2 awaits** ... `await Task.Run(async () => await ...)` means that it is not fire and forrget as it is inside `async Task Dosomething()` – Selvin Sep 18 '19 at 12:18
  • Yes you're right I totally missed the first await in case 2 – MDBarbier Sep 18 '19 at 14:29