このメソッドがあります:
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
の間で暗黙的な変換が発生しますか?そうでない場合、何が起こっていますか?どのように動作するように実装されていますか?
Task <>とintの間で暗黙的な変換が発生しますか?
いや。これは、async
/await
の機能の一部にすぎません。
async
として宣言されたメソッドには、戻り値の型が必要です。
void
(可能であれば避ける)Task
(完了/失敗の通知を超える結果はありません)Task<T>
(非同期的な方法でのT
型の論理結果用)コンパイラーはすべての適切なラッピングを行います。ポイントは、あなたが非同期urlContents.Length
を返すことです-実際のメソッドは最初のint
式にヒットしたときに戻るため、メソッドがawait
を返すようにすることはできませんもう完成された。その代わり、非同期メソッド自体が完了すると完了するTask<int>
を返します。
await
は逆のことを行うことに注意してください-it nwraps a Task<T>
をT
値に変換します。
string urlContents = await getStringTask;
...もちろん、非同期にラップを解除しますが、Result
を使用するとタスクが完了するまでブロックされます。 (await
は、awaitableパターンを実装する他の型をアンラップできますが、Task<T>
が最も頻繁に使用される可能性があります。)
この二重ラッピング/アンラッピングは、非同期を非常に構成可能にするものです。たとえば、あなたのものを呼び出して結果を2倍にする別の非同期メソッドを書くことができます:
public async Task<int> AccessTheWebAndDoubleAsync()
{
var task = AccessTheWebAsync();
int result = await task;
return result * 2;
}
(または単にreturn await AccessTheWebAsync() * 2;
もちろん。)
いいえ、タスクをintに変換する必要はありません。タスク結果を使用するだけです。
int taskResult = AccessTheWebAndDouble().Result;
public async Task<int> AccessTheWebAndDouble()
{
int task = AccessTheWeb();
return task;
}
可能な場合は値を返し、そうでない場合は0を返します。