我们有这个方法:
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
的反面相反 - 它将Task<T>
展开为T
值,这就是这条线的工作方式:
string urlContents = await getStringTask;
...但当然它是异步打开它,而只是使用Result
会阻塞,直到任务完成。 (await
可以解开实现等待模式的其他类型,但Task<T>
是您最常使用的那种。)
这种双重包装/解包是允许异步可组合的原因。例如,我可以编写另一个异步方法来调用你的结果并将结果加倍:
public async Task<int> AccessTheWebAndDoubleAsync()
{
var task = AccessTheWebAsync();
int result = await task;
return result * 2;
}
(或者当然只是return await AccessTheWebAsync() * 2;
。)
不需要将Task转换为int。只需使用任务结果。
int taskResult = AccessTheWebAndDouble().Result;
public async Task<int> AccessTheWebAndDouble()
{
int task = AccessTheWeb();
return task;
}
如果可用,它将返回值,否则返回0。