Why return type of async must be void, Task or Task

前端 未结 2 1507
执笔经年
执笔经年 2021-01-01 23:48

I am trying get my hands dirty with async CTP and I noticed that the compiler complains about the async return type. What is the problem with other types?

A simple d

2条回答
  •  予麋鹿
    予麋鹿 (楼主)
    2021-01-02 00:14

    On the await [consumption] side, we are flexible: we can await any type so long as it has the right methods.

    On the async method [production] side, we are inflexible: we are hard-coded to return only the Task type (or void). Why the inconsistency?

    1. Iterators already have this behavior...

      An iterator method (one which has a “yield” inside) is hard-coded to return either IEnumerable or IEnumerator. However, you can “foreach” over any type which has GetEnumerator/MoveNext/Current members. So Async is just following suite.

    2. A task is like a future, so it’s good to hard-code it...

      A Task is barely more than a future. A future is a basic fundamental part of a language/platform. There’s no reason for a language two have multiple copies of such a fundamental notion. One is enough. It’s so foundational that you might even add keywords to the language to deal with futures. Anyway, if someone has a future-like thing, or a richer notion of task, then they can build it out of Task or Func. (Our Tasks are already running. If you want to build something that’s “cold”, like F# asyncs or like IObservable, one which doesn’t start until you tell it – then you should build it out of a Func rather than out of a Task).

    3. Further subtleties

      Define this function:

      void f(Func> f)
      

      And invoke it:

      f( () => 1 + await t )
      

      We’d like to be able to infer that T=int in this case. Such inference isn’t possible unless the compiler has hard-coded knowledge that the lambda it passes to “f” has type Task.

    Source: Technical intro to the Async CTP

提交回复
热议问题