16

为了理解新的 async/await 模式,我有一个问题我找不到答案,即我是否应该用 async 装饰我的方法,如果我打算从其他 async 函数调用这些方法,或者只是 return Tasks在适当情况下?

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

class A<T>
{
      public async Task<T> foo1() //Should be consumed
      {
          return await foo2();
      }

      public async Task<T> foo2() //Could be consumed
      {
          return await foo3();
      }

      private async Task<T> foo3() //Private
      {
          return await Task.Run(...);
      }
}

class B<T>
{
      public async Task<T> foo1() //Should be consumed
      {
          return await foo2();
      }

      public async Task<T> foo2() //Could be consumed
      {
          return await foo3();
      }

      private Task<T> foo3() //Private
      {
          return Task.Run(...);
      }
}

class C<T>
{
      public async Task<T> foo1() //Should be consumed
      {
          return await foo2();
      }

      public Task<T> foo2() //Could be consumed
      {
          return foo3();
      }

      private Task<T> foo3() //Private
      {
          return Task.Run(...);
      }
}

过度装饰方法似乎是多余的,所以我自然倾向于C,但与此同时,Task<T>除非您使用await关键字,否则使用起来感觉有些尴尬。

4

2 回答 2

9

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

所以,它归结为一个权衡:您是否希望您的方法以稍微不那么可读为代价来提高效率?还是您愿意为了可读性而牺牲性能?

Usually, I would advise you to go for readability first and only focus on performance if profiling tells you it's worth it. But in this case, I think the increase in readability is small, so I would probably not use await.

Also note that your class C still doesn't go far enough: foo1() also doesn't need await.

于 2012-08-18T07:54:01.380 回答
2

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

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

于 2012-08-18T07:18:33.873 回答