Task <int>如何成为int?</int>

时间:2012-10-31 13:27:26

标签: c# .net asynchronous .net-4.5 c#-5.0

我们有这种方法:

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

2 个答案:

答案 0 :(得分:142)

  

在任务&lt;&gt;之间是否发生隐式转换和int?

不。这只是async / await工作方式的一部分。

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

  • void(尽可能避免)
  • Task(没有超出完成/失败通知的结果)
  • Task<T>(对于异步方式的T类型的逻辑结果)

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

请注意,await执行相反的操作 - 它将<{1}}展开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; } 。)

答案 1 :(得分:10)

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

int taskResult = AccessTheWebAndDouble().Result;

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

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