1

なぜasyncメソッドが Task オブジェクトを返すように指定する必要があるのか​​疑問に思います。

それを指定することは、キーワードと重複しているように見えます。また、実際にはオブジェクトasyncを作成していないため、混乱を招きます。Task

私が理解しているように、コンパイラは Task オブジェクトの作成に必要なコードを発行します (await 呼び出しであるか、戻り値を新しい Task でラップするかに関係なく)。

宣言型と戻り型の不一致はあまり好きではありません。

4

3 に答える 3

8

これは実際には問題ではありません。これは暴言であり、StackOverflow には特に適していません。

宣言型と戻り値の型の不一致はあまり好きではありません。

文句を言いたいなら、ブログを始めて、それについて文句を言いましょう。それを質問として再定式化しましょう:

メソッドによって返される宣言された型はasync、たとえば である可能性がありますTask<int>が、そのメソッドのステートメントによって返される式は、 ではなくreturnに暗黙的に変換可能でなければなりintませんTask<int>。これは混乱を招く可能性があります。この動作を正当化する設計原則は何ですか?

これが混乱を招く可能性があることは間違いありません。asyncメソッドは、私たちが 1 つのものとして考えるのに非常に慣れている 2 つのものを分離するため、混乱を招きます。それらの2つのことは次のとおりです。

  • このメソッドの呼び出し元で制御が再開されたときに返されるオブジェクトの型は?
  • メソッドからその継続に渡されるオブジェクトの型は? メソッドの継続は、メソッドの完了時に実行されるコードであることを忘れないでください。

同期メソッドでは、呼び出し元での再開ポイントが同期メソッドの継続であるため、これら 2 つのことは常に同じです。しかし、非同期メソッドの要点は、呼び出し元のコードがメソッドの継続ではないということです。メソッドの継続は、それに関連付けられたタスクの継続を設定することによって制御されます。

そのため、宣言された戻り値の型とreturnステートメントに指定された型が異なります。呼び出し元は を必要としてTask<int>いますが、メソッドの継続intは を必要としています。このreturnステートメントは、メソッドが同期であるか非同期であるかに関係なく、「このメソッドは完了しました。この値を継続に渡します」という意味です。

于 2013-05-29T15:02:46.760 に答える
5

public async int MyMethodAsync()実際に を返すメソッドとして自動的にコンパイルされない理由を尋ねているようですTask<int>

答えは、驚くことの少ない原則です。メソッド シグネチャで宣言された戻り値の型は、常に実際の戻り値の型です。
このようにして、メソッド宣言を読むときに、修飾子を調べたり特別なルールを覚えたりしなくても、メソッドを呼び出すときに見られる実際の戻り値の型を常に知ることができます。

于 2013-05-29T14:16:55.707 に答える