136

この方法があります:

async Task<int> AccessTheWebAsync()
{ 
    HttpClient client = new HttpClient();

   Task<string> getStringTask = client.GetStringAsync("http://msdn.microsoft.com");

   // You can do work here that doesn't rely on the string from GetStringAsync.
   DoIndependentWork();

   string urlContents = await getStringTask;
   //The thing is that this returns an int to a method that has a return type of Task<int>
   return urlContents.Length;
}

Task<int>と の間で暗黙の変換が発生しintますか? そうでない場合、何が起こっているのですか?動作するようにどのように実装されていますか?

4

2 に答える 2

204

Task<> と int の間で暗黙的な変換が行われますか?

いいえ。これはasync/のawait仕組みのほんの一部です。

として宣言されたメソッドはasync、次の戻り値の型を持つ必要があります。

  • void(できれば避けてください)
  • Task(完了/失敗の通知以上の結果はありません)
  • Task<T>T(非同期の型の論理結果の場合)

コンパイラは、すべての適切なラッピングを行います。ポイントは、あなたが非同期的に戻るということです -まだ完了していない最初の式にヒットしたときに実際のメソッドが戻るurlContents.Lengthため、メソッドを単に return にすることはできません。代わりに、async メソッド自体が完了すると完了する を返します。intawaitTask<int>

awaitは反対のことを行うことに注意してください - それは aを値にアンラップします。これがこの行の仕組みです:Task<T>T

string urlContents = await getStringTask;

...しかし、もちろん非同期でアンラップしますが、使用Resultするだけではタスクが完了するまでブロックされます。(await待機可能なパターンを実装する他の型をアンラップできTask<T>ますが、最も頻繁に使用する可能性が高い型です。)

この二重のラッピング/アンラッピングにより、async を非常に構成可能にすることができます。たとえば、あなたのメソッドを呼び出して結果を 2 倍にする別の非同期メソッドを作成できます。

public async Task<int> AccessTheWebAndDoubleAsync()
{
    var task = AccessTheWebAsync();
    int result = await task;
    return result * 2;
}

(またはもちろん単にreturn await AccessTheWebAsync() * 2;。)

于 2012-10-31T13:32:07.840 に答える