Task.Run(job)和job()之间有什么区别?等待Task.CompleteTask吗?

时间:2020-08-15 09:12:51

标签: c# .net .net-core async-await

我想使同步功能异步

public JobSync()
{
 // a lot of logic
}

两者

public async JobAsync()
{
 JobSync()
 await Task.CompleteTask;
}

Task.Run(()=>JobSync())

有效

但是两种方法之间有什么区别吗?

1 个答案:

答案 0 :(得分:7)

我想使同步功能异步

此版本完全不是异步的:

public async Task JobAsync()
{
    JobSync()
    await Task.CompleteTask;
}

它将完全同步运行,您只需通过async关键字添加不必要的开销即可。

此版本为“伪异步”:

Task.Run(()=>JobSync())

Task.Run仅在线程池上运行同步代码。但是,它确实会在运行Task之前返回一个JobSync,这对于您以UI应用为目标很有用,因为UI线程是在JobSync运行时释放的。

这里真正的问题是为什么您想使JobSync异步,答案是您不应该。

当该方法涉及I / O时,异步就产生了,因为可以在等待响应的同时释放线程以处理其他工作。

如果JobSync是冻结CPU的昂贵的CPU绑定方法,只需使用Task.Run进行调用即可:

await Task.Run(JobSync);

根据评论更新

如果您定位的API需要返回Task的方法,例如BackgroundService.ExecuteAsync,那么Task.FromResult是最有效的解决方法:

public override Task ExecuteAsync(CancellationToken ct)
{
    return Task.FromResult(JobSync());
}

这只是将JobSync()对象中的Task的结果转为满足ExecuteAsync的要求,但不会强制代码不必要地在ThreadPool上运行。