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;
}

Task<int>int之间是否发生隐式转换?如果不是,那会发生什么?如何实现它的工作?

145532 次浏览

Task < > 和 int 之间是否发生隐式转换?

没有,这只是 async/await工作原理的一部分。

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

  • void(尽可能避免)
  • Task(除了通知完成/失败外没有其他结果)
  • Task<T>(用于以异步方式获得 T类型的逻辑结果)

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

请注意,await做相反的事情——它从 解开 a 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;。)

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

int taskResult = AccessTheWebAndDouble().Result;


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

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