我们有这样的方法:

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之间?如果没有,那么发生了什么?它是如何实现的?

推荐答案

Does an implicit conversion occur between Task<> and int?

不.这只是async/await工作原理的一部分.

任何声明为async的方法的返回类型必须为:

  • void(尽可能避免)
  • Task(除完成/失败通知外无结果)
  • Task<T>(用于异步方式的T类型逻辑结果)

编译器执行所有适当的包装.关键是asynchronously返回urlContents.Length——你不能让这个方法只返回int,因为实际的方法会在到达尚未完成的第一个await表达式时返回.因此,它返回一个Task<int>,当异步方法本身完成时,它将完成.

请注意,await的作用正好相反——它是unwraps a Task<T>T的值,这就是这条线的工作原理:

string urlContents = await getStringTask;

... 当然,它会异步展开,而仅仅使用Result会一直阻塞,直到任务完成.(await可以展开实现等待模式的其他类型,但Task<T>可能是您最常用的类型.)

这种双重包装/解包是async如此可组合的原因.例如,我可以编写另一个异步方法来调用您的方法,并将结果加倍:

public async Task<int> AccessTheWebAndDoubleAsync()
{
    var task = AccessTheWebAsync();
    int result = await task;
    return result * 2;
}

(当然,也可以简简单单地说是return await AccessTheWebAsync() * 2;个.)

.net相关问答推荐

Azure管道-使用.NET 8 RC2 SDK生成C#项目失败

是否必须使用 Visual Studio 预览才能使用 MAUI?

无法使用 int.Parse 从字符串转换值

.NET - WindowStyle = hidden 与 CreateNoWindow = true?

ICommand MVVM 实现

如何在 C# 中创建 Word 文档?

为什么 Interlocked.Exchange 不支持布尔类型?

String 是原始类型吗?

如何正确停止BackgroundWorker

C# 属性实际上是方法吗?

我们应该总是在类中包含一个默认构造函数吗?

软件包版本始终为 1.0.0,带有 dotnet pack

是否有可用的 WPF 备忘单?

如何在 C# 中以编程方式安装 Windows 服务?

Find() 和 First() 抛出异常,如何改为返回 null?

将字典值转换为数组

将两个列表映射到 C# 中的字典中

立即检测客户端与服务器套接字的断开连接

MailMessage,Sender 和 From 属性的区别

使用 LINQ 搜索树