为什么在异步函数使用Task.Run不返回任务>
问题描述:
考虑下面的代码片段,其中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
可能是有益的?
答
返回Task<int>
的原因是您正在调用Task.Run(Func<Task<TResult>>)
重载,它将返回一个任务,该任务充当您的函数返回的任务的代理。如果你想使用原来的过载,你可以指定泛型类型参数:
至于你的第二个问题:在一个异步操作使用Task.Run
是有益的,当上述操作也有一个同步的一部分,其由此在后台线程上执行,而不是阻塞原始线程。例如,StreamWriter.WriteAsync
可能需要将该字符串序列化为字节数组,然后才能将其异步写入磁盘。序列化是同步完成的,并且可能受益于在后台线程上运行。