Task<int>是如何实现的?变成一个int? [英] How does Task<int> become an int?
问题描述
我们有这个方法:
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
之间是否发生了隐式转换?如果不是,那么发生了什么?它是如何实现工作的?
Does an implicit conversion occur between Task<int>
and int
? If not, then what is happening? How is it implemented to work?
推荐答案
Task<> 和 int 之间是否发生了隐式转换?
Does an implicit conversion occur between Task<> and int?
没有.这只是 async
/await
工作原理的一部分.
Nope. This is just part of how async
/await
works.
任何声明为 async
的方法必须有一个返回类型:
Any method declared as async
has to have a return type of:
void
(尽可能避免)Task
(除了完成/失败通知之外没有结果)Task
(用于异步方式的T
类型的逻辑结果)
void
(avoid if possible)Task
(no result beyond notification of completion/failure)Task<T>
(for a logical result of typeT
in an async manner)
编译器进行所有适当的包装.关键是你异步返回urlContents.Length
——你不能让方法只返回int
,因为实际方法会当它遇到第一个尚未完成的 await
表达式时返回.因此,它返回一个 Task
,它将在异步方法本身完成时完成.
The compiler does all the appropriate wrapping. The point is that you're asynchronously returning urlContents.Length
- you can't make the method just return int
, as the actual method will return when it hits the first await
expression which hasn't already completed. So instead, it returns a Task<int>
which will complete when the async method itself completes.
注意 await
做相反的事情 - 它展开一个 Task
到一个 T
值,这就是这条线的工作原理:
Note that await
does the opposite - it unwraps a Task<T>
to a T
value, which is how this line works:
string urlContents = await getStringTask;
...但当然它会异步解包,而仅使用 Result
会阻塞,直到任务完成.(await
可以解开其他实现可等待模式的类型,但 Task
是您可能最常使用的类型.)
... but of course it unwraps it asynchronously, whereas just using Result
would block until the task had completed. (await
can unwrap other types which implement the awaitable pattern, but Task<T>
is the one you're likely to use most often.)
这种双重包装/展开使异步变得如此可组合.例如,我可以编写另一个异步方法来调用您的方法并将结果加倍:
This dual wrapping/unwrapping is what allows async to be so composable. For example, I could write another async method which calls yours and doubles the result:
public async Task<int> AccessTheWebAndDoubleAsync()
{
var task = AccessTheWebAsync();
int result = await task;
return result * 2;
}
(或者干脆return await AccessTheWebAsync() * 2;
当然.)
这篇关于Task<int>是如何实现的?变成一个int?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!