任务如何? 成为一个int?

问题描述 投票:91回答:2

我们有这个方法:

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

c# .net asynchronous .net-4.5 c#-5.0
2个回答
143
投票

在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;。)


10
投票

不需要将Task转换为int。只需使用任务结果。

int taskResult = AccessTheWebAndDouble().Result;

public async Task<int> AccessTheWebAndDouble()
{
    int task = AccessTheWeb();
    return task;
}

如果可用,它将返回值,否则返回0。

© www.soinside.com 2019 - 2024. All rights reserved.