25

Should I add async/await to a single-line function like:

public async Task<T> GetFoo()
{
    return await HandleAsync<T>(....);
}

Or is this unneeded overhead if the parameter does not need an asynchron call and I can simple write:

public Task<T> GetFoo()
{
    return HandleAsync<T>(....);
}
Horcrux7
  • 23,758
  • 21
  • 98
  • 156
  • 2
    It's not that your function is a single line so you should not add async await, it's about your requirement if you want your method to run asynchronously then add. – Ipsit Gaur Oct 17 '17 at 08:28
  • 1
    No, because adding it doesn't improve readability. – qxg Oct 17 '17 at 08:29
  • @IpsitGaur Because HandleAsync runs already asynchron this execute in both cases asynchron. – Horcrux7 Oct 17 '17 at 08:37
  • 3
    You may find [this article](https://learn.microsoft.com/en-us/dotnet/csharp/async) a good read, specifically the bit about what happens under the covers. Basically, if you have no real need for `async` then don't use it as it adds unnecessary overhead – musefan Oct 17 '17 at 09:13

3 Answers3

10

Use second overload, because async methods are converted into astate machine behind the scenes (an extra class) to handle asynchronous operation with awaits.

So first method adds unnecessary overhead. Second overload simply returns a task that you can still await on.

Im not sure about how exception handling wold change here but i think it doesnt change.

M.kazem Akhgary
  • 18,645
  • 8
  • 57
  • 118
  • 5
    It's worth noting that the `await` approach might also cause an unneeded thread context switch (read "possible performance loss"), because no `ConfigureAwait(false)` is used. – dymanoid Oct 17 '17 at 09:09
  • 2
    As @Ipsut mentioned above - it is worth noting the OP's requirements. Whether he needs the result of `HandleAsync` or not. It is also worth noting the larger context of where the method is called. Is it fired with other `async` calls or is this call isolated. Context-switching will only become an issue if all threads are very busy. – ethane Oct 17 '17 at 20:09
0

well, it depends. If you 'just' want to return the task, that can be awaited outside this code, then no, you don't need to add it. However, you should await your async tasks, for unwanted side-effects. It depends per scenario.

Let's take a look at the following case:

public Task DownloadStream(Stream target)
{
 return _downloader.ToStream(target);
}

would return a Task, so where I would want to download and handle it, I would then await it, i.e.:

public async Task DownloadAsync()
{
  Using(var stream = new MemoryStream(){
    await DownloadStream(stream); //<== here i NEED to wait and not block the UI
  }
}

Hopefully you can interpretate it in your case.

Good luck!

Roelant M
  • 1,581
  • 1
  • 13
  • 28
0

I would add async/await in the case you describe. Largely, it's a matter of consistency - I want anyone reading my code to understand that this is an asynchronous function and returns a Task<T> - and clean style.

You might feel that this is extra ceremony you don't need and that's fine, it's a matter of personal taste. However, at the compiled code level, there will be very little difference if any. And of course, if you were really intense about reducing ceremony, you probably wouldn't be using C#.

Rich Bryant
  • 865
  • 10
  • 27
  • 9
    It's not a matter of personal taste, it's crucial for the performance and the reliability. And the generated IL code will be different. An `await` generates a state machine, including an unneeded thread synchronization context switch that might cause performance issues and even deadlocks. – dymanoid Oct 17 '17 at 09:25
  • 1
    _" I want anyone reading my code to understand that this is an asynchronous function"_ Which is done through the name of the method, not the code inside of it. Just like Handle**Async**, OP should name his method GetFoo**Async**. Using a second `await` is pointless, and as others have adressed, can actually cause issues. – Flater Oct 17 '17 at 09:31