异步一直向下?

试图理解新的异步/等待模式,我有一个问题,我找不到答案,即如果我应该用异步装饰我的方法,如果我打算从其他异步函数调用这些方法,或只是返回Task在适当的地方?

换句话说,这些A,B或C类中哪一个最好,为什么?

 class A { public async Task foo1() //Should be consumed { return await foo2(); } public async Task foo2() //Could be consumed { return await foo3(); } private async Task foo3() //Private { return await Task.Run(...); } } class B { public async Task foo1() //Should be consumed { return await foo2(); } public async Task foo2() //Could be consumed { return await foo3(); } private Task foo3() //Private { return Task.Run(...); } } class C { public async Task foo1() //Should be consumed { return await foo2(); } public Task foo2() //Could be consumed { return foo3(); } private Task foo3() //Private { return Task.Run(...); } } 

过度设计方法似乎是多余的,所以我自然倾向于C ,但同时使用Task感觉有些尴尬,除非你使用await关键字。

两个版本的工作效率相同,唯一的区别是当你await这里使用await ,会得到一些性能损失(因为必须设置状态机并且最有可能使用延续)。

因此,它取决于权衡:您是否希望您的方法更有效,但代价是可读性稍差? 或者您是否愿意为了可读性而牺牲性能?

通常,我会建议您首先考虑可读性,只关注性能,如果分析告诉您它是值得的。 但在这种情况下,我认为可读性的增加很小,所以我可能不会使用await

另请注意,您的C类仍然不够用: foo1()也不需要await

签名中的async允许编译器创建所包含代码的状态机重写,这是在一般情况下实现await语义所必需的。

您的示例正是您不需要重写的特殊情况:异步操作是方法中发生的最后一件事。 这种方法已经可以在.NET4.0有效。 当您不需要async时,这种兼容性可能是避免async一个原因。