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

前端 未结 2 1413
执笔经年
执笔经年 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<T>(Func<Task<T>> 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<int>.

    Source: Technical intro to the Async CTP

    0 讨论(0)
  • 2021-01-02 00:22

    Because a Task<TResult> is a "future" - a value that will be coming along later. A string[] is something you have right now.

    Similarly, Task is an operation that will complete (either successfully or with an error) sometime in the future.

    void is something of a special case; it represents a top-level operation in the Async CTP.

    If you're wondering why the Task isn't automatically inferred, this was considered but rejected by the Async CTP team. Their rationale is here, and this thread also covers it.

    0 讨论(0)
提交回复
热议问题