0

I have been trying to find out what is the difference between.

Task.Run(() => DoSomething());

and

 Task.Run(async() => await DoSomething());

I have been testing this and it does not look like it affects functionality. I am really confused which one to use if you want to run a task. I am calling awaitable task is this just a syntax sugar or is there a difference between those. Which one I should use and why? I am really curious because even if I store that task in a variable it still returns a Task for both cases.

and also we have asynchronous method

   private async Task DoSomething()
        {
     //do something here
        }

I found a great post here await Task.Run vs await explaining specific case of awaiting an async method in the event handler of a GUI application, but that explains only the difference between this

await Task.Run(async () => await LongProcessAsync());

and this

await LongProcessAsync();
Vladimir
  • 322
  • 1
  • 17
  • 3
    https://blog.stephencleary.com/2016/12/eliding-async-await.html – Johnathan Barclay Jan 14 '22 at 12:31
  • In fact, you don't need a lambda at all: `Task.Run(DoSomething);` is fine, as `DoSomething` will be implicitly converted to a `Func` as with the lambda. – Johnathan Barclay Jan 14 '22 at 12:33
  • Hello @JohnathanBarclay and thanks for your comment, if it is the same why I am getting warning from a VS code if I use Task.Run(DoSomething); warning is "Because this call is not awaited, execution of the current method continues before the call is completed. Consider applying the 'await' operator to the result of the call" – Vladimir Jan 14 '22 at 12:36
  • @JohnathanBarclay not getting any warning when using both of the lamdas – Vladimir Jan 14 '22 at 12:37
  • https://github.com/davidfowl/AspNetCoreDiagnosticScenarios/blob/master/AsyncGuidance.md – Oliver Jan 14 '22 at 12:40
  • 1
    You have to write `await Task.Run(DoSomething)`. – Oliver Jan 14 '22 at 12:41
  • 1
    @Vladimir The warning cannot relate to the delegate; it will be the `Task` returned from `Task.Run`. This [example](https://dotnetfiddle.net/2NijYh) shows the warning, even when a lambda is used. – Johnathan Barclay Jan 14 '22 at 12:45

1 Answers1

8

Lambda expressions create private methods under the hood. So this:

Task.Run(() => DoSomething());

becomes something like this:

Task.Run(__lambda);
private Task __lambda() => DoSomething();

So, asking what the difference is between these two lines:

Task.Run(() => DoSomething());
Task.Run(async() => await DoSomething());

is the same as asking what the difference is between these two methods:

private Task __lambda() => DoSomething();
private async Task __lambda() => await DoSomething();

I have a blog post that goes into detail. The summary answer is that if all you are doing is just calling DoSomething, then you can elide (remove) the async and await keywords. If the lambda is doing anything else (e.g., modifying arguments) that was removed from your question for simplicity, then I'd recommend keeping the async and await keywords.

As a general guideline: any trivial code can elide async/await; any logic should use async and await.

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