2017-08-04 134 views
1

考虑下面的代码片段,其中MyMethod及其异步版本MyMethodAsync被称为以不同的方式:为什么在异步函数使用Task.Run不返回任务<Task<T>>

using System; 
using System.Threading.Tasks; 

namespace ConsoleApplication1 
{ 
    class Program 
    { 
     static int MyMethod() 
     { 
      System.Threading.Thread.Sleep(1000); 

      return 42; 
     } 

     static async Task<int> MyMethodAsync() 
     { 
      await Task.Delay(1000); 

      return 42; 
     } 

     static void Main(string[] args) 
     { 
      var result1 = MyMethod(); // int 
      var result2 = MyMethodAsync(); // Task<int> 
      var result3 = Task.Run(() => MyMethod()); // Task<int> 
      var result4 = Task.Run(() => MyMethodAsync()); // Task<int> 
     } 
    } 
} 

在每一种情况下,我已评论返回类型。

问题是为什么result4的类型也是Task<int>?不应该是Task<Task<int>>

顺便说一句,是否有任何情况下调用异步方法Task.Run可能是有益的?

回答

1

返回Task<int>的原因是您正在调用Task.Run(Func<Task<TResult>>)重载,它将返回一个任务,该任务充当您的函数返回的任务的代理。如果你想使用原来的过载,你可以指定泛型类型参数:

至于你的第二个问题:在一个异步操作使用Task.Run是有益的,当上述操作也有一个同步的一部分,其由此在后台线程上执行,而不是阻塞原始线程。例如,StreamWriter.WriteAsync可能需要将该字符串序列化为字节数组,然后才能将其异步写入磁盘。序列化是同步完成的,并且可能受益于在后台线程上运行。

相关问题