Short answer is: yes, you can skip them in this case and yes, there's a performance penalty.
(简短的答案是:是的,在这种情况下可以跳过它们,是的,这会降低性能。)
When all your method does is await
once and immediately return, like this:
(当您的所有方法都await
一次并立即返回时,如下所示:)
async Task FooAsync()
{
/* ... */
await BarAsync();
}
then it would be pretty much equivalent to write:
(那么写起来就差不多了:)
Task FooAsync()
{
/* ... */
return BarAsync();
}
The meaning of async
is (from the perspective of FooAsync
): okay, the operation BarAsync
might take a while to complete, so if we get an uncompleted Task
from it let me save my current state and return the control flow up to my caller.
(async
的含义是(从FooAsync
的角度来看):好的, BarAsync
操作可能需要一段时间才能完成,因此,如果我们从中获取未完成的Task
,请让我保存当前状态并将控制流返回给调用者。)
Once the Task
gets completed, I want to pick up the state and continue what I've been doing. (Task
完成后,我想获取状态并继续执行我一直在做的事情。)
In this case it's clear that there is no additional work that would be performed after the BarAsync
Task
completes, so you can just return that Task
to the caller, since effectively FooAsync
completes the exact same moment that Task
would.
(在这种情况下,很明显,在BarAsync
Task
完成之后,没有其他工作可以执行,因此您可以将Task
返回给调用者,因为FooAsync
与Task
完全相同。)
There's no need to save any state or to schedule continuations. (无需保存任何状态或安排继续。)
The overhead for this is not huge when we're talking about a single call, but if you call this method many times you might feel an impact.
(当我们谈论单个调用时,此操作的开销并不大,但如果多次调用此方法,则可能会产生影响。)
The compiler has to set up the entire async
infrastructure the moment you declare your method to be async
- the state machine, continuation scheduling, the whole package. (编译器必须建立整个async
架构,你宣布你的方法的时刻是async
-状态机,延续调度,全包。)
So as a general rule: if you can simplify your method to not be async
but simply return another Task
, it's worth to do so. (因此,作为一般规则:如果您可以简化方法以使其不async
而仅返回另一个Task
,则值得这样做。)
As a side note: you certainly don't need to wrap your S1Async
call into a Task.Run
and you don't have to synchronously block in your Main
since C# 7.1.
(附带一提:您当然不需要将S1Async
调用包装到Task.Run
并且从C#7.1开始就不必同步阻塞Main
。)
You can just write: (您可以这样写:)
static async Task Main()
{
var result = await S1Async(1);
Console.WriteLine(result);
}