我们有这种方法:
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
之间是否发生隐式转换?如果没有,那么发生了什么?它是如何实现的?
答案 0 :(得分:142)
在任务&lt;&gt;之间是否发生隐式转换和int?
不。这只是async
/ await
工作方式的一部分。
声明为async
的任何方法都必须具有以下返回类型:
void
(尽可能避免)Task
(没有超出完成/失败通知的结果)Task<T>
(对于异步方式的T
类型的逻辑结果)编译器执行所有适当的包装。关键是你异步返回urlContents.Length
- 你不能让方法只返回int
,因为实际的方法会在它遇到第一个await
时返回1}}尚未完成的表达式。因此,它返回一个Task<int>
,它将在异步方法本身完成时完成。
请注意,await
执行相反的操作 - 它将<{1}}展开到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;
}
。)
答案 1 :(得分:10)
无需将Task转换为int。只需使用任务结果。
int taskResult = AccessTheWebAndDouble().Result;
public async Task<int> AccessTheWebAndDouble()
{
int task = AccessTheWeb();
return task;
}
如果可用,它将返回值,否则返回0.