此问题在此处已有答案:
await Task.Run vs await(3个答案)
18天前关门了。
谁能给我解释一下下面两个代码示例的行为有什么区别吗?哪一个更好/更安全?这是一个来自Repository实现的片段。
任务.运行
public Task<TDocument> FindByIdAsync(string id)
{
return Task.Run(() =>
{
var objectId = new ObjectId(id);
var filter = Builders<TDocument>.Filter.Eq(doc => doc.Id, objectId);
return _collection.Find(filter).SingleOrDefaultAsync();
});
}
字符串
异步任务
public async Task<TDocument> FindByIdAsync(string id)
{
var objectId = new ObjectId(id);
var filter = Builders<TDocument>.Filter.Eq(doc => doc.Id, objectId);
return await _collection.Find(filter).SingleOrDefaultAsync();
}
型
2条答案
按热度按时间yftpprvb1#
Task.Run
,如docs中所述:使指定的工作在
ThreadPool
上运行,并返回该工作的任务或Task<TResult>
句柄。也就是说,在这种情况下,它将强制执行线程池上的所有代码。通常
Task.Run
用于CPU限制的工作负载,例如,如果FindByIdAsync
在某个单线程SynchronizationContext
中执行,(例如,在桌面应用程序的UI线程中)并且SingleOrDefaultAsync
调用之前的代码是计算繁重的,它可能导致UI冻结,这是不希望的(它还将处理SingleOrDefaultAsync
不是“真正的SingleOrDefaultAsync
”的情况)。另一方面,如果你在没有同步上下文的“vanilla”ASP.NET Core中调用这个方法,那么在这种情况下使用
Task.Run
就没有多大意义了,第二种方法应该更好(它应该更有性能,尽管在很多情况下不是那么容易实现)。还假设这是用于查询某些数据库/存储的代码,并且客户端很可能是“真正的Java”(注意there are some nasty exceptions),那么使用第一个而不是第二个就没有多大意义了。
另请参阅:
4xrmg8kj2#
第一种方法适用于并行化CPU密集型工作,但在异步编程环境中,它不是最有效的方法,因为它会启动一个新任务并在不同的线程上运行代码,从而引入额外的开销。
第二种方法更有效,是处理异步操作的推荐方法。它不会引入不必要的上下文切换或额外的线程开销,使其成为异步代码的更好选择。
总而言之,
async/await
方法通常更适合处理Repository或任何其他异步代码中的异步操作,也更安全。更多详情:Task.Run vs Async Await