Every-time you call await it creates a lump of code to bundle up variables, captures the synchronization context (if applicable) and create a continuation into an IAsyncStateMachine.
Essentially, returning a Task without the async keyword will give you a small run-time efficiency and save you a bunch of CIL. Do note that the Async feature in .NET also has many optimizations already. Also note (and importantly) that returning a Task in a using statement will likely throw an Already Disposed Exception.
You can compare the CIL and plumbing differences here
So if your method is just forwarding a Task and not wanting anything from it, you could easily just drop the async keyword and return the Task directly.
More-so, there are times when we do more than just forwarding and there is branching involved. This is where, Task.FromResult and Task.CompletedTask come into play to help deal with the logic of what may arise in a method. I.e If you want to give a result (there and then), or return a Task that is completed (respectively).
Lastly, the Async and Await Pattern has subtle differences when dealing with Exceptions. If you are returning a Task, you can use Task.FromException<T> to pop any exception on the the returned Task like an async method would normally do.
Nonsensical example
public Task<int> DoSomethingAsync(int someValue) { try { if (someValue == 1) return Task.FromResult(3); // Return a completed task return MyAsyncMethod(); // Return a task } catch (Exception e) { return Task.FromException<int>(e); // Place exception on the task } }
In short, if you don't quite understand what is going on, just await it; the overhead will be minimal. However, if you understand the subtitles of how to return a task result, a completed task, placing an exception on a task, or just forwarding. You can save your self some CIL and give your code a small performance gain by dropping the async keyword returning a task directly and bypassing the IAsyncStateMachine.
At about this time, I would look up the Stack Overflow user and author Stephen Cleary, and Mr. Parallel Stephen Toub. They have a plethora of blogs and books dedicated solely to the Async and Await Pattern, all the pitfalls, coding etiquette and lots more information you will surely find interesting.
awaitit creates a lump of code and goes through a statemachine, by returning a task you are sometimes creating a small efficiency. However, there are situations that you might want to poke any exceptions on the returned task (that will be awaited). i think from here you want to start looking at Stephen Cleary and Stephen Toubs awesome blogs on the Async and Await PatternIt Depends. If you don't want to do anything with the result, you don't need to useawaitand can just return the value. Debugging becomes a bit harder though, as you can't check the return value inFunc2itself during debugging, nor can you handle exceptions locally.Prefer async/await over directly returning Task