Task<int>是如何实现的?变成一个int? [英] How does Task&lt;int&gt; become an int?

查看:85
本文介绍了Task<int>是如何实现的?变成一个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;
}

Taskint 之间是否发生了隐式转换?如果不是,那么发生了什么?它是如何实现工作的?

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 type T 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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆