.net 在这个上下文中,Task.Run和Bloc Task有什么区别?

vltsax25  于 2023-11-20  发布在  .NET
关注(0)|答案(2)|浏览(118)

此问题在此处已有答案

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();
    }

yftpprvb

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),那么使用第一个而不是第二个就没有多大意义了。
另请参阅:

4xrmg8kj

4xrmg8kj2#

第一种方法适用于并行化CPU密集型工作,但在异步编程环境中,它不是最有效的方法,因为它会启动一个新任务并在不同的线程上运行代码,从而引入额外的开销。
第二种方法更有效,是处理异步操作的推荐方法。它不会引入不必要的上下文切换或额外的线程开销,使其成为异步代码的更好选择。
总而言之,async/await方法通常更适合处理Repository或任何其他异步代码中的异步操作,也更安全。
更多详情:Task.Run vs Async Await

相关问题