Async all the way down?

泄露秘密 提交于 2019-12-18 03:56:13

问题


Trying to understand the new async/await pattern, I have one question which I can't find an answer to, namely if I should decorate my methods with async, if I intend to call those methods from other async functions, or just return Tasks where appropriate?

In other words, which of these classes A, B or C is best, and why?

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(...);
      }
}

It seems redundant to overdecorate methods so I naturally lean toward C, but at the same time it feels somewhat awkward to work with Task<T> unless you use the await keyword.


回答1:


Both versions work effectively the same, the only difference is that when you use await here, you get some performance penalty (because the state machine must be set up and a continuation will most likely be used).

So, it comes down to a tradeoff: Do you want your methods to be somewhat more efficient at the cost of being slightly less readable? Or are you willing to sacrifice performance for readability?

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.




回答2:


The async in the signature is there to allow the compiler to create the state-machine rewriting of the contained code that is necessary to implement the await semantics in the general case.

Your example is exactly the special case where you do not need that rewriting: The asynchronous operation is the last thing happening within a method. That kind of method is already possible and valid in .NET4.0. This compatibility might be one reason to avoid async when you do not need it.



来源:https://stackoverflow.com/questions/12016322/async-all-the-way-down

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!